From 0f1ce95635555db65edbcc83ae6e64204199703b Mon Sep 17 00:00:00 2001 From: Jean-Roland Gosse Date: Wed, 13 Nov 2024 15:19:31 +0100 Subject: [PATCH] Improve query/reply perf (#781) * fix: remove superfluous rc init * feat: lazify svec release * refactor: rename slice_empty as slice_null * feat: rework svec expand * refactor: z_bytes_append_slice * feat: lazify arc slice * feat: improve stirng/slice move * feat: lazify sample timestamp set * feat: add non-reader decode functions * feat: remove superfluous keyexpr clear * feat: add bytes alias arc * feat: add rx pool size config option * feat: use transport arc slice pool for payload decode * feat: n msg svec is now a transport resource pool * fix: add offset to svec init * feat: make svec use elem f a per call arg * feat: skip ke suffix check * fix: arc pool * feat: improve sub perf and readability * feat: add z_string_alias_slice function * feat: align queryable with subscription * feat: align reply with sub & queryables * feat: nothing to clear in frame * fix: reply clean up * feat: streamline replies * feat: query is not a rc and store a session rc * fix: ci issues * fix: attachment examples * fix: keyexpr equals * fix: flaky test --- examples/unix/c11/z_get_attachment.c | 7 +- examples/unix/c11/z_queryable_attachment.c | 7 +- examples/unix/c11/z_sub_attachment.c | 8 +- include/zenoh-pico/api/types.h | 2 +- include/zenoh-pico/collections/bytes.h | 6 +- include/zenoh-pico/collections/refcount.h | 27 +-- include/zenoh-pico/collections/slice.h | 4 +- include/zenoh-pico/collections/string.h | 3 +- include/zenoh-pico/collections/vec.h | 72 ++++--- include/zenoh-pico/config.h | 5 - include/zenoh-pico/config.h.in | 5 - include/zenoh-pico/net/query.h | 29 ++- include/zenoh-pico/net/reply.h | 26 ++- include/zenoh-pico/net/sample.h | 19 +- include/zenoh-pico/net/session.h | 4 + include/zenoh-pico/protocol/codec/core.h | 2 +- include/zenoh-pico/protocol/codec/message.h | 8 +- include/zenoh-pico/protocol/codec/network.h | 8 +- include/zenoh-pico/protocol/codec/transport.h | 8 +- include/zenoh-pico/protocol/core.h | 7 +- .../zenoh-pico/protocol/definitions/network.h | 4 +- include/zenoh-pico/session/query.h | 2 +- include/zenoh-pico/session/queryable.h | 27 ++- include/zenoh-pico/session/reply.h | 2 +- include/zenoh-pico/session/session.h | 4 +- include/zenoh-pico/session/subscription.h | 7 +- include/zenoh-pico/transport/transport.h | 4 + src/api/api.c | 54 ++--- src/collections/arc_slice.c | 5 +- src/collections/bytes.c | 16 +- src/collections/slice.c | 9 +- src/collections/string.c | 8 +- src/collections/vec.c | 18 +- src/net/query.c | 36 +--- src/net/reply.c | 53 +---- src/net/sample.c | 31 +-- src/net/session.c | 4 +- src/protocol/codec.c | 49 +++-- src/protocol/codec/message.c | 18 +- src/protocol/codec/network.c | 22 +- src/protocol/codec/transport.c | 97 ++++++--- src/protocol/core.c | 2 +- src/protocol/definitions/message.c | 5 +- src/protocol/definitions/transport.c | 6 +- src/protocol/keyexpr.c | 11 +- src/session/query.c | 132 +++++------- src/session/queryable.c | 200 +++++++++++++----- src/session/reply.c | 2 +- src/session/rx.c | 5 +- src/session/scout.c | 2 +- src/session/subscription.c | 67 ++++-- src/session/utils.c | 8 + src/transport/common/rx.c | 6 +- src/transport/multicast/read.c | 3 +- src/transport/multicast/rx.c | 6 +- src/transport/multicast/transport.c | 9 +- src/transport/raweth/rx.c | 2 +- src/transport/unicast/read.c | 3 +- src/transport/unicast/rx.c | 6 +- src/transport/unicast/transport.c | 11 +- tests/modularity.py | 18 +- tests/z_msgcodec_test.c | 38 ++-- 62 files changed, 711 insertions(+), 558 deletions(-) diff --git a/examples/unix/c11/z_get_attachment.c b/examples/unix/c11/z_get_attachment.c index 65404138b..2d7ddcccc 100644 --- a/examples/unix/c11/z_get_attachment.c +++ b/examples/unix/c11/z_get_attachment.c @@ -68,12 +68,11 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { // Check attachment const z_loaned_bytes_t *attachment = z_sample_attachment(sample); - if (attachment == NULL) { - return; - } ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); size_t attachment_len; - ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) < 0) { + return; + } kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); diff --git a/examples/unix/c11/z_queryable_attachment.c b/examples/unix/c11/z_queryable_attachment.c index 20a2e9ad2..ace30bb48 100644 --- a/examples/unix/c11/z_queryable_attachment.c +++ b/examples/unix/c11/z_queryable_attachment.c @@ -68,10 +68,9 @@ void query_handler(z_loaned_query_t *query, void *ctx) { // Check attachment const z_loaned_bytes_t *attachment = z_query_attachment(query); - if (attachment != NULL) { - ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); - size_t attachment_len; - ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) == Z_OK) { kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); diff --git a/examples/unix/c11/z_sub_attachment.c b/examples/unix/c11/z_sub_attachment.c index 5720f86fd..823280673 100644 --- a/examples/unix/c11/z_sub_attachment.c +++ b/examples/unix/c11/z_sub_attachment.c @@ -64,12 +64,10 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { printf(" with timestamp: %" PRIu64 "\n", z_timestamp_ntp64_time(ts)); } // Check attachment - const z_loaned_bytes_t *attachment = z_sample_attachment(sample); - if (attachment != NULL) { - ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); - size_t attachment_len; - ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) == Z_OK) { kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index 53010ece7..26c703161 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -125,7 +125,7 @@ _Z_OWNED_TYPE_VALUE(_z_queryable_t, queryable) /** * Represents a Zenoh Query entity, received by Zenoh Queryable entities. */ -_Z_OWNED_TYPE_RC(_z_query_rc_t, query) +_Z_OWNED_TYPE_VALUE(_z_query_t, query) /** * Represents the encoding of a payload, in a MIME-like format. diff --git a/include/zenoh-pico/collections/bytes.h b/include/zenoh-pico/collections/bytes.h index 9f3ad16ef..fa2ea573c 100644 --- a/include/zenoh-pico/collections/bytes.h +++ b/include/zenoh-pico/collections/bytes.h @@ -28,7 +28,7 @@ inline size_t _z_arc_slice_size(const _z_arc_slice_t *s) { return sizeof(_z_arc_slice_t); } _Z_ELEM_DEFINE(_z_arc_slice, _z_arc_slice_t, _z_arc_slice_size, _z_arc_slice_drop, _z_arc_slice_copy, _z_arc_slice_move) -_Z_SVEC_DEFINE(_z_arc_slice, _z_arc_slice_t, true) +_Z_SVEC_DEFINE(_z_arc_slice, _z_arc_slice_t) /*-------- Bytes --------*/ /** @@ -44,6 +44,9 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_bytes_t _z_bytes_null(void) { return (_z_bytes_t){0}; } +static inline void _z_bytes_alias_arc_slice(_z_bytes_t *dst, _z_arc_slice_t *s) { + dst->_slices = _z_arc_slice_svec_alias_element(s); +} bool _z_bytes_check(const _z_bytes_t *bytes); z_result_t _z_bytes_append_bytes(_z_bytes_t *dst, _z_bytes_t *src); z_result_t _z_bytes_append_slice(_z_bytes_t *dst, _z_arc_slice_t *s); @@ -51,6 +54,7 @@ z_result_t _z_bytes_copy(_z_bytes_t *dst, const _z_bytes_t *src); _z_bytes_t _z_bytes_duplicate(const _z_bytes_t *src); void _z_bytes_move(_z_bytes_t *dst, _z_bytes_t *src); void _z_bytes_drop(_z_bytes_t *bytes); +void _z_bytes_aliased_drop(_z_bytes_t *bytes); void _z_bytes_free(_z_bytes_t **bs); size_t _z_bytes_num_slices(const _z_bytes_t *bs); _z_arc_slice_t *_z_bytes_get_slice(const _z_bytes_t *bs, size_t i); diff --git a/include/zenoh-pico/collections/refcount.h b/include/zenoh-pico/collections/refcount.h index bcbd8f411..f1ad023f0 100644 --- a/include/zenoh-pico/collections/refcount.h +++ b/include/zenoh-pico/collections/refcount.h @@ -76,11 +76,10 @@ size_t _z_simple_rc_strong_count(void *cnt); return p; \ } \ static inline name##_rc_t name##_rc_clone(const name##_rc_t *p) { \ - name##_rc_t c = name##_rc_null(); \ if (_z_rc_increase_strong(p->_cnt) == _Z_RES_OK) { \ - c = *p; \ + return *p; \ } \ - return c; \ + return name##_rc_null(); \ } \ static inline name##_rc_t *name##_rc_clone_as_ptr(const name##_rc_t *p) { \ name##_rc_t *c = (name##_rc_t *)z_malloc(sizeof(name##_rc_t)); \ @@ -93,12 +92,10 @@ size_t _z_simple_rc_strong_count(void *cnt); return c; \ } \ static inline name##_weak_t name##_rc_clone_as_weak(const name##_rc_t *p) { \ - name##_weak_t c = name##_weak_null(); \ if (_z_rc_increase_weak(p->_cnt) == _Z_RES_OK) { \ - c._val = p->_val; \ - c._cnt = p->_cnt; \ + return (name##_weak_t){._val = p->_val, ._cnt = p->_cnt}; \ } \ - return c; \ + return name##_weak_null(); \ } \ static inline name##_weak_t *name##_rc_clone_as_weak_ptr(const name##_rc_t *p) { \ name##_weak_t *c = (name##_weak_t *)z_malloc(sizeof(name##_weak_t)); \ @@ -137,20 +134,17 @@ size_t _z_simple_rc_strong_count(void *cnt); return res; \ } \ static inline name##_weak_t name##_weak_clone(const name##_weak_t *p) { \ - name##_weak_t c = name##_weak_null(); \ if (_z_rc_increase_weak(p->_cnt) == _Z_RES_OK) { \ - c = *p; \ + return *p; \ } \ - return c; \ + return name##_weak_null(); \ } \ static inline void name##_weak_copy(name##_weak_t *dst, const name##_weak_t *p) { *dst = name##_weak_clone(p); } \ static inline name##_rc_t name##_weak_upgrade(const name##_weak_t *p) { \ - name##_rc_t c = name##_rc_null(); \ if (_z_rc_weak_upgrade(p->_cnt) == _Z_RES_OK) { \ - c._val = p->_val; \ - c._cnt = p->_cnt; \ + return (name##_rc_t){._val = p->_val, ._cnt = p->_cnt}; \ } \ - return c; \ + return name##_rc_null(); \ } \ static inline bool name##_weak_eq(const name##_weak_t *left, const name##_weak_t *right) { \ return (left->_val == right->_val); \ @@ -200,11 +194,10 @@ size_t _z_simple_rc_strong_count(void *cnt); return p; \ } \ static inline name##_simple_rc_t name##_simple_rc_clone(const name##_simple_rc_t *p) { \ - name##_simple_rc_t c = name##_simple_rc_null(); \ if (_z_simple_rc_increase(p->_cnt) == _Z_RES_OK) { \ - c = *p; \ + return *p; \ } \ - return c; \ + return name##_simple_rc_null(); \ } \ static inline name##_simple_rc_t *name##_simple_rc_clone_as_ptr(const name##_simple_rc_t *p) { \ name##_simple_rc_t *c = (name##_simple_rc_t *)z_malloc(sizeof(name##_simple_rc_t)); \ diff --git a/include/zenoh-pico/collections/slice.h b/include/zenoh-pico/collections/slice.h index 00101c185..58bc8d610 100644 --- a/include/zenoh-pico/collections/slice.h +++ b/include/zenoh-pico/collections/slice.h @@ -51,8 +51,8 @@ typedef struct { _z_delete_context_t _delete_context; } _z_slice_t; -static inline _z_slice_t _z_slice_empty(void) { return (_z_slice_t){0}; } -static inline void _z_slice_reset(_z_slice_t *bs) { *bs = _z_slice_empty(); } +static inline _z_slice_t _z_slice_null(void) { return (_z_slice_t){0}; } +static inline void _z_slice_reset(_z_slice_t *bs) { *bs = _z_slice_null(); } static inline bool _z_slice_is_empty(const _z_slice_t *bs) { return bs->len == 0; } static inline bool _z_slice_check(const _z_slice_t *slice) { return slice->start != NULL; } static inline _z_slice_t _z_slice_alias(const _z_slice_t bs) { diff --git a/include/zenoh-pico/collections/string.h b/include/zenoh-pico/collections/string.h index 37c1a218b..6291db854 100644 --- a/include/zenoh-pico/collections/string.h +++ b/include/zenoh-pico/collections/string.h @@ -76,6 +76,7 @@ static inline _z_string_t _z_string_alias(const _z_string_t str) { _z_string_t _z_string_copy_from_str(const char *value); _z_string_t _z_string_copy_from_substr(const char *value, size_t len); _z_string_t *_z_string_copy_from_str_as_ptr(const char *value); +_z_string_t _z_string_alias_slice(const _z_slice_t *slice); _z_string_t _z_string_alias_str(const char *value); _z_string_t _z_string_alias_substr(const char *value, size_t len); _z_string_t _z_string_from_str_custom_deleter(char *value, _z_delete_context_t c); @@ -98,7 +99,7 @@ _z_string_t _z_string_convert_bytes(const _z_slice_t *bs); _z_string_t _z_string_preallocate(const size_t len); _Z_ELEM_DEFINE(_z_string, _z_string_t, _z_string_len, _z_string_clear, _z_string_copy, _z_string_move) -_Z_SVEC_DEFINE(_z_string, _z_string_t, true) +_Z_SVEC_DEFINE(_z_string, _z_string_t) _Z_LIST_DEFINE(_z_string, _z_string_t) _Z_INT_MAP_DEFINE(_z_string, _z_string_t) diff --git a/include/zenoh-pico/collections/vec.h b/include/zenoh-pico/collections/vec.h index 3d5e48605..c3d9ff525 100644 --- a/include/zenoh-pico/collections/vec.h +++ b/include/zenoh-pico/collections/vec.h @@ -81,7 +81,10 @@ typedef struct { static inline _z_svec_t _z_svec_null(void) { return (_z_svec_t){0}; } static inline _z_svec_t _z_svec_alias(const _z_svec_t *src) { return *src; } -void _z_svec_init(_z_svec_t *dst, size_t element_size); +static inline _z_svec_t _z_svec_alias_element(void *element) { + return (_z_svec_t){._capacity = 1, ._len = 1, ._val = element}; +} +void _z_svec_init(_z_svec_t *v, size_t offset, size_t element_size); _z_svec_t _z_svec_make(size_t capacity, size_t element_size); z_result_t _z_svec_copy(_z_svec_t *dst, const _z_svec_t *src, z_element_copy_f copy, size_t element_size, bool use_elem_f); @@ -103,39 +106,40 @@ void _z_svec_clear(_z_svec_t *v, z_element_clear_f f, size_t element_size); void _z_svec_free(_z_svec_t **v, z_element_clear_f f, size_t element_size); void _z_svec_release(_z_svec_t *v); -#define _Z_SVEC_DEFINE(name, type, use_elem_f) \ - typedef _z_svec_t name##_svec_t; \ - static inline name##_svec_t name##_svec_null(void) { return _z_svec_null(); } \ - static inline name##_svec_t name##_svec_make(size_t capacity) { return _z_svec_make(capacity, sizeof(type)); } \ - static inline void name##_svec_init(name##_svec_t *v) { _z_svec_init(v, sizeof(type)); } \ - static inline size_t name##_svec_len(const name##_svec_t *v) { return _z_svec_len(v); } \ - static inline bool name##_svec_is_empty(const name##_svec_t *v) { return _z_svec_is_empty(v); } \ - static inline z_result_t name##_svec_expand(name##_svec_t *v) { \ - return _z_svec_expand(v, name##_elem_move, sizeof(type), use_elem_f); \ - } \ - static inline z_result_t name##_svec_append(name##_svec_t *v, const type *e) { \ - return _z_svec_append(v, e, name##_elem_move, sizeof(type), use_elem_f); \ - } \ - static inline type *name##_svec_get(const name##_svec_t *v, size_t pos) { \ - return (type *)_z_svec_get(v, pos, sizeof(type)); \ - } \ - static inline type *name##_svec_get_mut(name##_svec_t *v, size_t pos) { \ - return (type *)_z_svec_get_mut(v, pos, sizeof(type)); \ - } \ - static inline void name##_svec_set(name##_svec_t *v, size_t pos, type *e) { \ - _z_svec_set(v, pos, e, name##_elem_clear, sizeof(type)); \ - } \ - static inline void name##_svec_remove(name##_svec_t *v, size_t pos) { \ - _z_svec_remove(v, pos, name##_elem_clear, name##_elem_move, sizeof(type), use_elem_f); \ - } \ - static inline z_result_t name##_svec_copy(name##_svec_t *dst, const name##_svec_t *src) { \ - return _z_svec_copy(dst, src, name##_elem_copy, sizeof(type), use_elem_f); \ - } \ - static inline name##_svec_t name##_svec_alias(const name##_svec_t *v) { return _z_svec_alias(v); } \ - static inline void name##_svec_move(name##_svec_t *dst, name##_svec_t *src) { _z_svec_move(dst, src); } \ - static inline void name##_svec_reset(name##_svec_t *v) { _z_svec_reset(v, name##_elem_clear, sizeof(type)); } \ - static inline void name##_svec_clear(name##_svec_t *v) { _z_svec_clear(v, name##_elem_clear, sizeof(type)); } \ - static inline void name##_svec_release(name##_svec_t *v) { _z_svec_release(v); } \ +#define _Z_SVEC_DEFINE(name, type) \ + typedef _z_svec_t name##_svec_t; \ + static inline name##_svec_t name##_svec_null(void) { return _z_svec_null(); } \ + static inline name##_svec_t name##_svec_make(size_t capacity) { return _z_svec_make(capacity, sizeof(type)); } \ + static inline void name##_svec_init(name##_svec_t *v, size_t offset) { _z_svec_init(v, offset, sizeof(type)); } \ + static inline size_t name##_svec_len(const name##_svec_t *v) { return _z_svec_len(v); } \ + static inline bool name##_svec_is_empty(const name##_svec_t *v) { return _z_svec_is_empty(v); } \ + static inline z_result_t name##_svec_expand(name##_svec_t *v, bool use_elem_f) { \ + return _z_svec_expand(v, name##_elem_move, sizeof(type), use_elem_f); \ + } \ + static inline z_result_t name##_svec_append(name##_svec_t *v, const type *e, bool use_elem_f) { \ + return _z_svec_append(v, e, name##_elem_move, sizeof(type), use_elem_f); \ + } \ + static inline type *name##_svec_get(const name##_svec_t *v, size_t pos) { \ + return (type *)_z_svec_get(v, pos, sizeof(type)); \ + } \ + static inline type *name##_svec_get_mut(name##_svec_t *v, size_t pos) { \ + return (type *)_z_svec_get_mut(v, pos, sizeof(type)); \ + } \ + static inline void name##_svec_set(name##_svec_t *v, size_t pos, type *e) { \ + _z_svec_set(v, pos, e, name##_elem_clear, sizeof(type)); \ + } \ + static inline void name##_svec_remove(name##_svec_t *v, size_t pos, bool use_elem_f) { \ + _z_svec_remove(v, pos, name##_elem_clear, name##_elem_move, sizeof(type), use_elem_f); \ + } \ + static inline z_result_t name##_svec_copy(name##_svec_t *dst, const name##_svec_t *src, bool use_elem_f) { \ + return _z_svec_copy(dst, src, name##_elem_copy, sizeof(type), use_elem_f); \ + } \ + static inline name##_svec_t name##_svec_alias(const name##_svec_t *v) { return _z_svec_alias(v); } \ + static inline name##_svec_t name##_svec_alias_element(type *e) { return _z_svec_alias_element((void *)e); } \ + static inline void name##_svec_move(name##_svec_t *dst, name##_svec_t *src) { _z_svec_move(dst, src); } \ + static inline void name##_svec_reset(name##_svec_t *v) { _z_svec_reset(v, name##_elem_clear, sizeof(type)); } \ + static inline void name##_svec_clear(name##_svec_t *v) { _z_svec_clear(v, name##_elem_clear, sizeof(type)); } \ + static inline void name##_svec_release(name##_svec_t *v) { _z_svec_release(v); } \ static inline void name##_svec_free(name##_svec_t **v) { _z_svec_free(v, name##_elem_clear, sizeof(type)); } #endif /* ZENOH_PICO_COLLECTIONS_VECTOR_H */ diff --git a/include/zenoh-pico/config.h b/include/zenoh-pico/config.h index 2449535fe..5b946505f 100644 --- a/include/zenoh-pico/config.h +++ b/include/zenoh-pico/config.h @@ -177,11 +177,6 @@ */ #define Z_GET_TIMEOUT_DEFAULT 10000 -/** - * Average size of a frame message (bytes). Used to evaluate initial decoding frame size. - */ -#define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 - /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/config.h.in b/include/zenoh-pico/config.h.in index d6f43e3d3..4e75ac0cb 100644 --- a/include/zenoh-pico/config.h.in +++ b/include/zenoh-pico/config.h.in @@ -177,11 +177,6 @@ */ #define Z_GET_TIMEOUT_DEFAULT 10000 -/** - * Average size of a frame message (bytes). Used to evaluate initial decoding frame size. - */ -#define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 - /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/net/query.h b/include/zenoh-pico/net/query.h index 703688a65..4cf60a4f7 100644 --- a/include/zenoh-pico/net/query.h +++ b/include/zenoh-pico/net/query.h @@ -25,23 +25,25 @@ * The query to be answered by a queryable. */ typedef struct _z_query_t { - _z_value_t _value; _z_keyexpr_t _key; + _z_value_t _value; uint32_t _request_id; - _z_session_weak_t _zn; // Can't be an rc because of cross referencing - _z_bytes_t attachment; - char *_parameters; + _z_session_rc_t _zn; + _z_bytes_t _attachment; + _z_string_t _parameters; bool _anyke; } _z_query_t; // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_query_t _z_query_null(void) { return (_z_query_t){0}; } +static inline bool _z_query_check(const _z_query_t *query) { + return _z_keyexpr_check(&query->_key) || _z_value_check(&query->_value) || _z_bytes_check(&query->_attachment) || + _z_string_check(&query->_parameters); +} void _z_query_clear(_z_query_t *q); z_result_t _z_query_copy(_z_query_t *dst, const _z_query_t *src); void _z_query_free(_z_query_t **query); -_Z_REFCOUNT_DEFINE(_z_query, _z_query) - /** * Return type when declaring a queryable. */ @@ -54,8 +56,19 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_queryable_t _z_queryable_null(void) { return (_z_queryable_t){0}; } static inline bool _z_queryable_check(const _z_queryable_t *queryable) { return !_Z_RC_IS_NULL(&queryable->_zn); } -_z_query_t _z_query_create(_z_value_t *value, _z_keyexpr_t *key, const _z_slice_t *parameters, _z_session_rc_t *zn, - uint32_t request_id, const _z_bytes_t attachment); +static inline _z_query_t _z_query_alias(_z_value_t *value, _z_keyexpr_t *key, const _z_slice_t *parameters, + _z_session_rc_t *zn, uint32_t request_id, const _z_bytes_t *attachment, + bool anyke) { + return (_z_query_t){ + ._key = *key, + ._value = *value, + ._request_id = request_id, + ._zn = *zn, + ._attachment = *attachment, + ._parameters = _z_string_alias_slice(parameters), + ._anyke = anyke, + }; +} void _z_queryable_clear(_z_queryable_t *qbl); void _z_queryable_free(_z_queryable_t **qbl); diff --git a/include/zenoh-pico/net/reply.h b/include/zenoh-pico/net/reply.h index fcc8876c8..f352be9a1 100644 --- a/include/zenoh-pico/net/reply.h +++ b/include/zenoh-pico/net/reply.h @@ -59,11 +59,6 @@ typedef struct _z_reply_data_t { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_reply_data_t _z_reply_data_null(void) { return (_z_reply_data_t){0}; } -static inline _z_reply_data_t _z_reply_data_init(void) { - _z_reply_data_t reply_data = _z_reply_data_null(); - reply_data._tag = _Z_REPLY_TAG_NONE; - return reply_data; -} void _z_reply_data_clear(_z_reply_data_t *rd); z_result_t _z_reply_data_copy(_z_reply_data_t *dst, const _z_reply_data_t *src); @@ -85,14 +80,27 @@ typedef struct _z_reply_t { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_reply_t _z_reply_null(void) { return (_z_reply_t){0}; } +static inline _z_reply_t _z_reply_alias(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, + const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, + const _z_bytes_t *attachment) { + _z_reply_t r; + r.data.replier_id = id; + r.data._tag = _Z_REPLY_TAG_DATA; + r.data._result.sample = _z_sample_alias(keyexpr, payload, timestamp, encoding, kind, _Z_N_QOS_DEFAULT, attachment, + Z_RELIABILITY_DEFAULT); + return r; +} +static inline _z_reply_t _z_reply_err_alias(const _z_bytes_t *payload, _z_encoding_t *encoding) { + _z_reply_t r; + r.data._tag = _Z_REPLY_TAG_ERROR; + r.data._result.error.payload = *payload; + r.data._result.error.encoding = *encoding; + return r; +} _z_reply_t _z_reply_move(_z_reply_t *src_reply); void _z_reply_clear(_z_reply_t *src); void _z_reply_free(_z_reply_t **hello); z_result_t _z_reply_copy(_z_reply_t *dst, const _z_reply_t *src); -_z_reply_t _z_reply_create(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, - const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, - const _z_bytes_t *attachment); -_z_reply_t _z_reply_err_create(const _z_bytes_t payload, _z_encoding_t *encoding); typedef struct _z_pending_reply_t { _z_reply_t _reply; diff --git a/include/zenoh-pico/net/sample.h b/include/zenoh-pico/net/sample.h index ab42e6985..718fe95da 100644 --- a/include/zenoh-pico/net/sample.h +++ b/include/zenoh-pico/net/sample.h @@ -46,6 +46,21 @@ static inline bool _z_sample_check(const _z_sample_t *sample) { return _z_keyexpr_check(&sample->keyexpr) || _z_encoding_check(&sample->encoding) || _z_bytes_check(&sample->payload) || _z_bytes_check(&sample->attachment); } +static inline _z_sample_t _z_sample_alias(const _z_keyexpr_t *key, const _z_bytes_t *payload, + const _z_timestamp_t *timestamp, const _z_encoding_t *encoding, + const z_sample_kind_t kind, const _z_qos_t qos, const _z_bytes_t *attachment, + z_reliability_t reliability) { + return (_z_sample_t){ + .keyexpr = *key, + .payload = *payload, + .timestamp = *timestamp, + .encoding = *encoding, + .kind = kind, + .qos = qos, + .attachment = *attachment, + .reliability = reliability, + }; +} void _z_sample_move(_z_sample_t *dst, _z_sample_t *src); /** @@ -59,8 +74,4 @@ void _z_sample_free(_z_sample_t **sample); z_result_t _z_sample_copy(_z_sample_t *dst, const _z_sample_t *src); _z_sample_t _z_sample_duplicate(const _z_sample_t *src); -void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, _z_bytes_t *attachment, - z_reliability_t reliability); - #endif /* ZENOH_PICO_SAMPLE_NETAPI_H */ diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index b2bdd8fec..5362c1921 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -21,6 +21,7 @@ #include "zenoh-pico/collections/list.h" #include "zenoh-pico/config.h" #include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/session/queryable.h" #include "zenoh-pico/session/session.h" #include "zenoh-pico/session/subscription.h" #include "zenoh-pico/utils/config.h" @@ -61,6 +62,9 @@ typedef struct _z_session_t { // Session queryables #if Z_FEATURE_QUERYABLE == 1 _z_session_queryable_rc_list_t *_local_queryable; +#if Z_FEATURE_RX_CACHE == 1 + _z_queryable_cache_t _queryable_cache; +#endif #endif #if Z_FEATURE_QUERY == 1 _z_pending_query_list_t *_pending_queries; diff --git a/include/zenoh-pico/protocol/codec/core.h b/include/zenoh-pico/protocol/codec/core.h index c86d1b18c..16cdef966 100644 --- a/include/zenoh-pico/protocol/codec/core.h +++ b/include/zenoh-pico/protocol/codec/core.h @@ -61,7 +61,7 @@ z_result_t _z_slice_val_decode_na(_z_slice_t *bs, _z_zbuf_t *zbf); z_result_t _z_slice_encode(_z_wbuf_t *buf, const _z_slice_t *bs); z_result_t _z_slice_decode(_z_slice_t *bs, _z_zbuf_t *buf); -z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf); +z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf, _z_arc_slice_t *arcs); z_result_t _z_bytes_encode(_z_wbuf_t *wbf, const _z_bytes_t *bs); z_result_t _z_zbuf_read_exact(_z_zbuf_t *zbf, uint8_t *dest, size_t length); diff --git a/include/zenoh-pico/protocol/codec/message.h b/include/zenoh-pico/protocol/codec/message.h index c9bd9c039..b2d5c625c 100644 --- a/include/zenoh-pico/protocol/codec/message.h +++ b/include/zenoh-pico/protocol/codec/message.h @@ -19,19 +19,19 @@ #include "zenoh-pico/protocol/iobuf.h" z_result_t _z_push_body_encode(_z_wbuf_t *wbf, const _z_push_body_t *pshb); -z_result_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_query_encode(_z_wbuf_t *wbf, const _z_msg_query_t *query); z_result_t _z_query_decode(_z_msg_query_t *query, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_reply_encode(_z_wbuf_t *wbf, const _z_msg_reply_t *reply); -z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_err_encode(_z_wbuf_t *wbf, const _z_msg_err_t *err); -z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_put_encode(_z_wbuf_t *wbf, const _z_msg_put_t *put); -z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_del_encode(_z_wbuf_t *wbf, const _z_msg_del_t *del); z_result_t _z_del_decode(_z_msg_del_t *del, _z_zbuf_t *zbf, uint8_t header); diff --git a/include/zenoh-pico/protocol/codec/network.h b/include/zenoh-pico/protocol/codec/network.h index 64a5229c8..e3bce1f14 100644 --- a/include/zenoh-pico/protocol/codec/network.h +++ b/include/zenoh-pico/protocol/codec/network.h @@ -20,11 +20,11 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/iobuf.h" z_result_t _z_push_encode(_z_wbuf_t *wbf, const _z_n_msg_push_t *msg); -z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_request_encode(_z_wbuf_t *wbf, const _z_n_msg_request_t *msg); -z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_response_encode(_z_wbuf_t *wbf, const _z_n_msg_response_t *msg); -z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_response_final_encode(_z_wbuf_t *wbf, const _z_n_msg_response_final_t *msg); z_result_t _z_response_final_decode(_z_n_msg_response_final_t *msg, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_declare_encode(_z_wbuf_t *wbf, const _z_n_msg_declare_t *decl); @@ -33,6 +33,6 @@ z_result_t _z_n_interest_encode(_z_wbuf_t *wbf, const _z_n_msg_interest_t *inter z_result_t _z_n_interest_decode(_z_n_msg_interest_t *interest, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_network_message_encode(_z_wbuf_t *wbf, const _z_network_message_t *msg); -z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf); +z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_t *arcs); #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_NETWORK_H */ diff --git a/include/zenoh-pico/protocol/codec/transport.h b/include/zenoh-pico/protocol/codec/transport.h index 06bb26327..4a83857b1 100644 --- a/include/zenoh-pico/protocol/codec/transport.h +++ b/include/zenoh-pico/protocol/codec/transport.h @@ -22,7 +22,8 @@ z_result_t _z_scouting_message_encode(_z_wbuf_t *buf, const _z_scouting_message_ z_result_t _z_scouting_message_decode(_z_scouting_message_t *msg, _z_zbuf_t *buf); z_result_t _z_transport_message_encode(_z_wbuf_t *buf, const _z_transport_message_t *msg); -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *buf); +z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *buf, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool); z_result_t _z_join_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_join_t *msg); z_result_t _z_join_decode(_z_t_msg_join_t *msg, _z_zbuf_t *zbf, uint8_t header); @@ -40,11 +41,10 @@ z_result_t _z_keep_alive_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_k z_result_t _z_keep_alive_decode(_z_t_msg_keep_alive_t *msg, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_t *msg); -z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool); z_result_t _z_fragment_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_fragment_t *msg); z_result_t _z_fragment_decode(_z_t_msg_fragment_t *msg, _z_zbuf_t *zbf, uint8_t header); -z_result_t _z_transport_message_encode(_z_wbuf_t *wbf, const _z_transport_message_t *msg); -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf); #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_TRANSPORT_H */ diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index e66e3745e..c793656bd 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -70,7 +70,9 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_timestamp_t _z_timestamp_null(void) { return (_z_timestamp_t){0}; } -static inline bool _z_timestamp_check(const _z_timestamp_t *stamp) { return stamp->valid; } +static inline void _z_timestamp_invalid(_z_timestamp_t *tstamp) { tstamp->valid = false; } +static inline bool _z_timestamp_check(const _z_timestamp_t *tstamp) { return tstamp->valid; } +void _z_timestamp_copy(_z_timestamp_t *dst, const _z_timestamp_t *src); _z_timestamp_t _z_timestamp_duplicate(const _z_timestamp_t *tstamp); void _z_timestamp_clear(_z_timestamp_t *tstamp); void _z_timestamp_move(_z_timestamp_t *dst, _z_timestamp_t *src); @@ -170,6 +172,9 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_value_t _z_value_null(void) { return (_z_value_t){0}; } +static inline bool _z_value_check(const _z_value_t *value) { + return _z_bytes_check(&value->payload) || _z_encoding_check(&value->encoding); +} _z_value_t _z_value_steal(_z_value_t *value); z_result_t _z_value_copy(_z_value_t *dst, const _z_value_t *src); void _z_value_move(_z_value_t *dst, _z_value_t *src); diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index c3ea611f8..24d86102c 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -91,7 +91,7 @@ static inline bool _z_n_qos_get_express(_z_n_qos_t n_qos) { return (bool)(n_qos. #define _z_n_qos_make(express, nodrop, priority) \ _z_n_qos_create((bool)express, nodrop ? Z_CONGESTION_CONTROL_BLOCK : Z_CONGESTION_CONTROL_DROP, \ (z_priority_t)priority) -#define _Z_N_QOS_DEFAULT _z_n_qos_make(0, 0, 5) +#define _Z_N_QOS_DEFAULT ((_z_qos_t){._val = 5}) // RESPONSE FINAL message flags: // Z Extensions if Z==1 then Zenoh extensions are present @@ -290,7 +290,7 @@ void _z_n_msg_free(_z_network_message_t **m); inline static void _z_msg_clear(_z_zenoh_message_t *msg) { _z_n_msg_clear(msg); } inline static void _z_msg_free(_z_zenoh_message_t **msg) { _z_n_msg_free(msg); } _Z_ELEM_DEFINE(_z_network_message, _z_network_message_t, _z_noop_size, _z_n_msg_clear, _z_noop_copy, _z_noop_move) -_Z_SVEC_DEFINE(_z_network_message, _z_network_message_t, false) +_Z_SVEC_DEFINE(_z_network_message, _z_network_message_t) void _z_msg_fix_mapping(_z_zenoh_message_t *msg, uint16_t mapping); _z_network_message_t _z_msg_make_query(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_slice_t) parameters, _z_zint_t qid, diff --git a/include/zenoh-pico/session/query.h b/include/zenoh-pico/session/query.h index 9a8ea69ae..c1267e348 100644 --- a/include/zenoh-pico/session/query.h +++ b/include/zenoh-pico/session/query.h @@ -27,7 +27,7 @@ _z_zint_t _z_get_query_id(_z_session_t *zn); _z_pending_query_t *_z_get_pending_query_by_id(_z_session_t *zn, const _z_zint_t id); z_result_t _z_register_pending_query(_z_session_t *zn, _z_pending_query_t *pq); -z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, _z_zint_t reply_context, const _z_keyexpr_t keyexpr, +z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, _z_zint_t reply_context, _z_keyexpr_t *keyexpr, _z_msg_put_t *msg, z_sample_kind_t kind); z_result_t _z_trigger_query_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *msg); z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id); diff --git a/include/zenoh-pico/session/queryable.h b/include/zenoh-pico/session/queryable.h index 4498a5bed..6e8e8eeed 100644 --- a/include/zenoh-pico/session/queryable.h +++ b/include/zenoh-pico/session/queryable.h @@ -16,20 +16,37 @@ #define ZENOH_PICO_SESSION_QUERYABLE_H #include +#include -#include "zenoh-pico/net/session.h" +// Forward declaration to avoid cyclical include +typedef struct _z_session_t _z_session_t; +typedef struct _z_session_rc_t _z_session_rc_t; + +// Queryable infos +typedef struct { + _z_query_handler_t callback; + void *arg; +} _z_queryable_infos_t; + +_Z_ELEM_DEFINE(_z_queryable_infos, _z_queryable_infos_t, _z_noop_size, _z_noop_clear, _z_noop_copy, _z_noop_move) +_Z_SVEC_DEFINE(_z_queryable_infos, _z_queryable_infos_t) + +typedef struct { + _z_keyexpr_t ke_in; + _z_keyexpr_t ke_out; + _z_queryable_infos_svec_t infos; + size_t qle_nb; +} _z_queryable_cache_t; #if Z_FEATURE_QUERYABLE == 1 #define _Z_QUERYABLE_COMPLETE_DEFAULT false #define _Z_QUERYABLE_DISTANCE_DEFAULT 0 /*------------------ Queryable ------------------*/ +void _z_queryable_cache_clear(_z_queryable_cache_t *cache); _z_session_queryable_rc_t *_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id); -_z_session_queryable_rc_list_t *_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t key); - _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_session_queryable_t *q); -z_result_t _z_trigger_queryables(_z_session_rc_t *zn, _z_msg_query_t *query, const _z_keyexpr_t q_key, uint32_t qid, - const _z_bytes_t attachment); +z_result_t _z_trigger_queryables(_z_session_rc_t *zn, _z_msg_query_t *query, _z_keyexpr_t *q_key, uint32_t qid); void _z_unregister_session_queryable(_z_session_t *zn, _z_session_queryable_rc_t *q); void _z_flush_session_queryable(_z_session_t *zn); #endif diff --git a/include/zenoh-pico/session/reply.h b/include/zenoh-pico/session/reply.h index c10aa0b28..083fed40f 100644 --- a/include/zenoh-pico/session/reply.h +++ b/include/zenoh-pico/session/reply.h @@ -22,7 +22,7 @@ #ifndef ZENOH_PICO_SESSION_REPLY_H #define ZENOH_PICO_SESSION_REPLY_H -z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t key, _z_msg_reply_t *reply); +z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t *key, _z_msg_reply_t *reply); z_result_t _z_trigger_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *error); diff --git a/include/zenoh-pico/session/session.h b/include/zenoh-pico/session/session.h index d2aa10129..6296ad1f1 100644 --- a/include/zenoh-pico/session/session.h +++ b/include/zenoh-pico/session/session.h @@ -80,12 +80,12 @@ typedef struct { } _z_publication_t; // Forward type declaration to avoid cyclical include -typedef struct _z_query_rc_t _z_query_rc_t; +typedef struct _z_query_t _z_query_t; /** * The callback signature of the functions handling query messages. */ -typedef void (*_z_query_handler_t)(_z_query_rc_t *query, void *arg); +typedef void (*_z_query_handler_t)(_z_query_t *query, void *arg); typedef struct { _z_keyexpr_t _key; diff --git a/include/zenoh-pico/session/subscription.h b/include/zenoh-pico/session/subscription.h index 2d7e1187a..852e6cd9d 100644 --- a/include/zenoh-pico/session/subscription.h +++ b/include/zenoh-pico/session/subscription.h @@ -29,16 +29,17 @@ typedef struct { } _z_subscription_infos_t; _Z_ELEM_DEFINE(_z_subscription_infos, _z_subscription_infos_t, _z_noop_size, _z_noop_clear, _z_noop_copy, _z_noop_move) -_Z_SVEC_DEFINE(_z_subscription_infos, _z_subscription_infos_t, false) +_Z_SVEC_DEFINE(_z_subscription_infos, _z_subscription_infos_t) typedef struct { _z_keyexpr_t ke_in; _z_keyexpr_t ke_out; _z_subscription_infos_svec_t infos; + size_t sub_nb; } _z_subscription_cache_t; /*------------------ Subscription ------------------*/ -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +void _z_trigger_local_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, _z_bytes_t *attachment, z_reliability_t reliability); @@ -50,7 +51,7 @@ void _z_subscription_cache_clear(_z_subscription_cache_t *cache); _z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, uint8_t is_local, const _z_zint_t id); _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_t *sub); -z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +z_result_t _z_trigger_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, const _z_n_qos_t qos, _z_bytes_t *attachment, z_reliability_t reliability); void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub); diff --git a/include/zenoh-pico/transport/transport.h b/include/zenoh-pico/transport/transport.h index 678bf2022..e78de9366 100644 --- a/include/zenoh-pico/transport/transport.h +++ b/include/zenoh-pico/transport/transport.h @@ -69,6 +69,8 @@ _z_transport_peer_entry_list_t *_z_transport_peer_entry_list_insert(_z_transport // Forward type declaration to avoid cyclical include typedef struct _z_session_rc_t _z_session_rc_ref_t; +#define _Z_RES_POOL_INIT_SIZE 8 // Arbitrary small value + typedef struct { _z_session_rc_ref_t *_session; _z_link_t _link; @@ -79,6 +81,8 @@ typedef struct { _z_zint_t _sn_res; _z_zint_t _sn_tx_reliable; _z_zint_t _sn_tx_best_effort; + _z_arc_slice_svec_t _arc_pool; + _z_network_message_svec_t _msg_pool; volatile _z_zint_t _lease; volatile bool _transmitted; #if Z_FEATURE_MULTI_THREAD == 1 diff --git a/src/api/api.c b/src/api/api.c index d74130335..93c811f0b 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -66,7 +66,7 @@ void z_string_array_new(z_owned_string_array_t *a) { a->_val = _z_string_array_n size_t z_string_array_push_by_alias(z_loaned_string_array_t *a, const z_loaned_string_t *value) { _z_string_t str = _z_string_alias(*value); - _z_string_svec_append(a, &str); + _z_string_svec_append(a, &str, true); return _z_string_svec_len(a); } @@ -74,7 +74,7 @@ size_t z_string_array_push_by_alias(z_loaned_string_array_t *a, const z_loaned_s size_t z_string_array_push_by_copy(z_loaned_string_array_t *a, const z_loaned_string_t *value) { _z_string_t str; _z_string_copy(&str, value); - _z_string_svec_append(a, &str); + _z_string_svec_append(a, &str, true); return _z_string_svec_len(a); } @@ -244,12 +244,12 @@ const uint8_t *z_slice_data(const z_loaned_slice_t *slice) { return slice->start size_t z_slice_len(const z_loaned_slice_t *slice) { return slice->len; } -void z_slice_empty(z_owned_slice_t *slice) { slice->_val = _z_slice_empty(); } +void z_slice_empty(z_owned_slice_t *slice) { slice->_val = _z_slice_null(); } bool z_slice_is_empty(const z_loaned_slice_t *slice) { return _z_slice_is_empty(slice); } z_result_t z_bytes_to_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst) { - dst->_val = _z_slice_empty(); + dst->_val = _z_slice_null(); return _z_bytes_to_slice(bytes, &dst->_val); } @@ -417,17 +417,16 @@ z_query_consolidation_t z_query_consolidation_none(void) { z_query_consolidation_t z_query_consolidation_default(void) { return z_query_consolidation_auto(); } void z_query_parameters(const z_loaned_query_t *query, z_view_string_t *parameters) { - parameters->_val = _z_string_alias_str(_Z_RC_IN_VAL(query)->_parameters); + parameters->_val = _z_string_alias(query->_parameters); } -const z_loaned_bytes_t *z_query_attachment(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->attachment; } +const z_loaned_bytes_t *z_query_attachment(const z_loaned_query_t *query) { return &query->_attachment; } -const z_loaned_keyexpr_t *z_query_keyexpr(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_key; } +const z_loaned_keyexpr_t *z_query_keyexpr(const z_loaned_query_t *query) { return &query->_key; } -const z_loaned_bytes_t *z_query_payload(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_value.payload; } -const z_loaned_encoding_t *z_query_encoding(const z_loaned_query_t *query) { - return &_Z_RC_IN_VAL(query)->_value.encoding; -} +const z_loaned_bytes_t *z_query_payload(const z_loaned_query_t *query) { return &query->_value.payload; } + +const z_loaned_encoding_t *z_query_encoding(const z_loaned_query_t *query) { return &query->_value.encoding; } void z_closure_sample_call(const z_loaned_closure_sample_t *closure, z_loaned_sample_t *sample) { if (closure->call != NULL) { @@ -470,16 +469,13 @@ _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_config_t, config, _z_config_check, _z_config_nu _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_string_t, string, _z_string_check, _z_string_null, _z_string_copy, _z_string_clear) -bool _z_value_check(const _z_value_t *value) { - return _z_encoding_check(&value->encoding) || _z_bytes_check(&value->payload); -} _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_value_t, reply_err, _z_value_check, _z_value_null, _z_value_copy, _z_value_clear) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexpr_null, _z_keyexpr_copy, _z_keyexpr_clear) _Z_VIEW_FUNCTIONS_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexpr_null) _Z_VIEW_FUNCTIONS_IMPL(_z_string_t, string, _z_string_check, _z_string_null) -_Z_VIEW_FUNCTIONS_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_empty) +_Z_VIEW_FUNCTIONS_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_null) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_hello_t, hello, _z_hello_check, _z_hello_null, _z_hello_copy, _z_hello_clear) @@ -517,11 +513,11 @@ z_result_t z_whatami_to_view_string(z_whatami_t whatami, z_view_string_t *str_ou bool _z_string_array_check(const _z_string_svec_t *val) { return !_z_string_svec_is_empty(val); } z_result_t _z_string_array_copy(_z_string_svec_t *dst, const _z_string_svec_t *src) { - return _z_string_svec_copy(dst, src); + return _z_string_svec_copy(dst, src, true); } _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_string_svec_t, string_array, _z_string_array_check, _z_string_array_null, _z_string_array_copy, _z_string_svec_clear) -_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_empty, _z_slice_copy, _z_slice_clear) +_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_null, _z_slice_copy, _z_slice_clear) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_bytes_t, bytes, _z_bytes_check, _z_bytes_null, _z_bytes_copy, _z_bytes_drop) _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL(_z_bytes_writer_t, bytes_writer, _z_bytes_writer_check, _z_bytes_writer_empty, _z_bytes_writer_clear) @@ -1121,7 +1117,7 @@ bool z_reply_replier_id(const z_loaned_reply_t *reply, z_id_t *out_id) { #endif #if Z_FEATURE_QUERYABLE == 1 -_Z_OWNED_FUNCTIONS_RC_IMPL(query) +_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_query_t, query, _z_query_check, _z_query_null, _z_query_copy, _z_query_clear) void _z_queryable_drop(_z_queryable_t *queryable) { _z_undeclare_queryable(queryable); @@ -1191,9 +1187,7 @@ void z_query_reply_options_default(z_query_reply_options_t *options) { z_result_t z_query_reply(const z_loaned_query_t *query, const z_loaned_keyexpr_t *keyexpr, z_moved_bytes_t *payload, const z_query_reply_options_t *options) { - // Try upgrading session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&_Z_RC_IN_VAL(query)->_zn); - if (_Z_RC_IS_NULL(&sess_rc)) { + if (_Z_RC_IS_NULL(&query->_zn)) { return _Z_ERR_SESSION_CLOSED; } // Set options @@ -1208,12 +1202,11 @@ z_result_t z_query_reply(const z_loaned_query_t *query, const z_loaned_keyexpr_t _z_value_t value = {.payload = _z_bytes_from_owned_bytes(&payload->_this), .encoding = _z_encoding_from_owned(&opts.encoding->_this)}; - z_result_t ret = _z_send_reply(_Z_RC_IN_VAL(query), &sess_rc, keyexpr_aliased, value, Z_SAMPLE_KIND_PUT, + z_result_t ret = _z_send_reply(query, &query->_zn, keyexpr_aliased, value, Z_SAMPLE_KIND_PUT, opts.congestion_control, opts.priority, opts.is_express, opts.timestamp, _z_bytes_from_owned_bytes(&opts.attachment->_this)); z_bytes_drop(payload); // Clean-up - _z_session_rc_drop(&sess_rc); z_encoding_drop(opts.encoding); z_bytes_drop(opts.attachment); return ret; @@ -1229,9 +1222,7 @@ void z_query_reply_del_options_default(z_query_reply_del_options_t *options) { z_result_t z_query_reply_del(const z_loaned_query_t *query, const z_loaned_keyexpr_t *keyexpr, const z_query_reply_del_options_t *options) { - // Try upgrading session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&_Z_RC_IN_VAL(query)->_zn); - if (_Z_RC_IS_NULL(&sess_rc)) { + if (_Z_RC_IS_NULL(&query->_zn)) { return _Z_ERR_SESSION_CLOSED; } _z_keyexpr_t keyexpr_aliased = _z_keyexpr_alias_from_user_defined(*keyexpr, true); @@ -1244,11 +1235,10 @@ z_result_t z_query_reply_del(const z_loaned_query_t *query, const z_loaned_keyex _z_value_t value = {.payload = _z_bytes_null(), .encoding = _z_encoding_null()}; - z_result_t ret = _z_send_reply(_Z_RC_IN_VAL(query), &sess_rc, keyexpr_aliased, value, Z_SAMPLE_KIND_DELETE, + z_result_t ret = _z_send_reply(query, &query->_zn, keyexpr_aliased, value, Z_SAMPLE_KIND_DELETE, opts.congestion_control, opts.priority, opts.is_express, opts.timestamp, _z_bytes_from_owned_bytes(&opts.attachment->_this)); // Clean-up - _z_session_rc_drop(&sess_rc); z_bytes_drop(opts.attachment); return ret; } @@ -1257,9 +1247,7 @@ void z_query_reply_err_options_default(z_query_reply_err_options_t *options) { o z_result_t z_query_reply_err(const z_loaned_query_t *query, z_moved_bytes_t *payload, const z_query_reply_err_options_t *options) { - // Try upgrading session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&_Z_RC_IN_VAL(query)->_zn); - if (_Z_RC_IS_NULL(&sess_rc)) { + if (_Z_RC_IS_NULL(&query->_zn)) { return _Z_ERR_SESSION_CLOSED; } z_query_reply_err_options_t opts; @@ -1271,9 +1259,7 @@ z_result_t z_query_reply_err(const z_loaned_query_t *query, z_moved_bytes_t *pay // Set value _z_value_t value = {.payload = _z_bytes_from_owned_bytes(&payload->_this), .encoding = _z_encoding_from_owned(&opts.encoding->_this)}; - - z_result_t ret = _z_send_reply_err(_Z_RC_IN_VAL(query), &sess_rc, value); - _z_session_rc_drop(&sess_rc); + z_result_t ret = _z_send_reply_err(query, &query->_zn, value); z_bytes_drop(payload); // Clean-up z_encoding_drop(opts.encoding); diff --git a/src/collections/arc_slice.c b/src/collections/arc_slice.c index 17d17a8eb..28603aff9 100644 --- a/src/collections/arc_slice.c +++ b/src/collections/arc_slice.c @@ -36,9 +36,6 @@ _z_arc_slice_t _z_arc_slice_wrap_slice_rc(_z_slice_simple_rc_t* slice_rc, size_t assert(offset + len <= _Z_RC_IN_VAL(slice_rc)->len); _z_arc_slice_t arc_s; arc_s.slice = _z_slice_simple_rc_clone(slice_rc); - if (_Z_RC_IS_NULL(&arc_s.slice)) { - return _z_arc_slice_empty(); - } arc_s.len = len; arc_s.start = offset; return arc_s; @@ -79,6 +76,6 @@ z_result_t _z_arc_slice_move(_z_arc_slice_t* dst, _z_arc_slice_t* src) { z_result_t _z_arc_slice_drop(_z_arc_slice_t* s) { _z_slice_simple_rc_drop(&s->slice); - *s = _z_arc_slice_empty(); + s->len = 0; return _Z_RES_OK; } diff --git a/src/collections/bytes.c b/src/collections/bytes.c index deb3f8252..ab3507a95 100644 --- a/src/collections/bytes.c +++ b/src/collections/bytes.c @@ -28,7 +28,7 @@ bool _z_bytes_check(const _z_bytes_t *bytes) { return !_z_bytes_is_empty(bytes); } z_result_t _z_bytes_copy(_z_bytes_t *dst, const _z_bytes_t *src) { - return _z_arc_slice_svec_copy(&dst->_slices, &src->_slices); + return _z_arc_slice_svec_copy(&dst->_slices, &src->_slices, true); } _z_bytes_t _z_bytes_duplicate(const _z_bytes_t *src) { @@ -63,6 +63,8 @@ _z_arc_slice_t *_z_bytes_get_slice(const _z_bytes_t *bs, size_t i) { void _z_bytes_drop(_z_bytes_t *bytes) { _z_arc_slice_svec_clear(&bytes->_slices); } +void _z_bytes_aliased_drop(_z_bytes_t *bytes) { _z_arc_slice_svec_reset(&bytes->_slices); } + void _z_bytes_free(_z_bytes_t **bs) { _z_bytes_t *ptr = *bs; @@ -93,7 +95,7 @@ z_result_t _z_bytes_from_slice(_z_bytes_t *b, _z_slice_t s) { *b = _z_bytes_null(); _z_arc_slice_t arc_s = _z_arc_slice_wrap(s, 0, s.len); if (_z_arc_slice_len(&arc_s) != s.len) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - return _z_arc_slice_svec_append(&b->_slices, &arc_s); + return _z_arc_slice_svec_append(&b->_slices, &arc_s, true); } z_result_t _z_bytes_from_buf(_z_bytes_t *b, const uint8_t *src, size_t len) { @@ -125,8 +127,12 @@ z_result_t _z_bytes_to_slice(const _z_bytes_t *bytes, _z_slice_t *s) { } z_result_t _z_bytes_append_slice(_z_bytes_t *dst, _z_arc_slice_t *s) { - _Z_CLEAN_RETURN_IF_ERR(_z_arc_slice_svec_append(&dst->_slices, s), _z_arc_slice_drop(s)); - return _Z_RES_OK; + z_result_t ret = _Z_RES_OK; + ret = _z_arc_slice_svec_append(&dst->_slices, s, true); + if (ret != _Z_RES_OK) { + _z_arc_slice_drop(s); + } + return ret; } z_result_t _z_bytes_append_bytes(_z_bytes_t *dst, _z_bytes_t *src) { @@ -149,7 +155,7 @@ _z_slice_t _z_bytes_try_get_contiguous(const _z_bytes_t *bs) { _z_arc_slice_t *arc_s = _z_bytes_get_slice(bs, 0); return _z_slice_alias_buf(_z_arc_slice_data(arc_s), _z_arc_slice_len(arc_s)); } - return _z_slice_empty(); + return _z_slice_null(); } void _z_bytes_move(_z_bytes_t *dst, _z_bytes_t *src) { diff --git a/src/collections/slice.c b/src/collections/slice.c index 5c9116ea7..049721a8a 100644 --- a/src/collections/slice.c +++ b/src/collections/slice.c @@ -111,22 +111,19 @@ z_result_t _z_slice_n_copy(_z_slice_t *dst, const _z_slice_t *src, size_t offset } void _z_slice_move(_z_slice_t *dst, _z_slice_t *src) { - dst->start = src->start; - dst->len = src->len; - dst->_delete_context = src->_delete_context; - + *dst = *src; _z_slice_reset(src); } _z_slice_t _z_slice_duplicate(const _z_slice_t *src) { - _z_slice_t dst = _z_slice_empty(); + _z_slice_t dst = _z_slice_null(); _z_slice_copy(&dst, src); return dst; } _z_slice_t _z_slice_steal(_z_slice_t *b) { _z_slice_t ret = *b; - *b = _z_slice_empty(); + *b = _z_slice_null(); return ret; } bool _z_slice_eq(const _z_slice_t *left, const _z_slice_t *right) { diff --git a/src/collections/string.c b/src/collections/string.c index a2545e767..2dad38f40 100644 --- a/src/collections/string.c +++ b/src/collections/string.c @@ -33,6 +33,12 @@ _z_string_t _z_string_copy_from_substr(const char *value, size_t len) { return s; } +_z_string_t _z_string_alias_slice(const _z_slice_t *slice) { + _z_string_t s; + s._slice = _z_slice_alias(*slice); + return s; +} + _z_string_t _z_string_alias_str(const char *value) { _z_string_t s; s._slice = _z_slice_alias_buf((const uint8_t *)(value), strlen(value)); @@ -71,7 +77,7 @@ z_result_t _z_string_copy_substring(_z_string_t *dst, const _z_string_t *src, si return _z_slice_n_copy(&dst->_slice, &src->_slice, offset, len); } -void _z_string_move(_z_string_t *dst, _z_string_t *src) { *dst = _z_string_steal(src); } +void _z_string_move(_z_string_t *dst, _z_string_t *src) { _z_slice_move(&dst->_slice, &src->_slice); } _z_string_t _z_string_steal(_z_string_t *str) { _z_string_t ret; diff --git a/src/collections/vec.c b/src/collections/vec.c index 60ee8f4a1..e37614cca 100644 --- a/src/collections/vec.c +++ b/src/collections/vec.c @@ -135,7 +135,7 @@ void _z_vec_remove(_z_vec_t *v, size_t pos, z_element_free_f free_f) { /*-------- svec --------*/ _z_svec_t _z_svec_make(size_t capacity, size_t element_size) { - _z_svec_t v = {._capacity = 0, ._len = 0, ._val = NULL}; + _z_svec_t v = _z_svec_null(); if (capacity != 0) { v._val = z_malloc(element_size * capacity); } @@ -145,7 +145,11 @@ _z_svec_t _z_svec_make(size_t capacity, size_t element_size) { return v; } -void _z_svec_init(_z_svec_t *dst, size_t element_size) { memset(dst->_val, 0, dst->_capacity * element_size); } +void _z_svec_init(_z_svec_t *v, size_t offset, size_t element_size) { + assert(offset <= v->_capacity); + void *start = _z_svec_get_mut(v, offset, element_size); + memset(start, 0, (v->_capacity - offset) * element_size); +} static inline void __z_svec_move_inner(void *dst, void *src, z_element_move_f move, size_t num_elements, size_t element_size, bool use_elem_f) { @@ -206,7 +210,7 @@ void _z_svec_clear(_z_svec_t *v, z_element_clear_f clear_f, size_t element_size) void _z_svec_release(_z_svec_t *v) { z_free(v->_val); - *v = _z_svec_null(); + v->_capacity = 0; } void _z_svec_free(_z_svec_t **v, z_element_clear_f clear, size_t element_size) { @@ -226,13 +230,13 @@ bool _z_svec_is_empty(const _z_svec_t *v) { return v->_len == 0; } z_result_t _z_svec_expand(_z_svec_t *v, z_element_move_f move, size_t element_size, bool use_elem_f) { // Allocate a new vector - size_t _capacity = v->_capacity == 0 ? 1 : (v->_capacity << 1); + size_t _capacity = v->_capacity << 1; void *_val = (void *)z_malloc(_capacity * element_size); if (_val == NULL) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } + // Move and clear old data __z_svec_move_inner(_val, v->_val, move, v->_len, element_size, use_elem_f); - // Free the old data z_free(v->_val); // Update the current vector v->_val = _val; @@ -241,7 +245,9 @@ z_result_t _z_svec_expand(_z_svec_t *v, z_element_move_f move, size_t element_si } z_result_t _z_svec_append(_z_svec_t *v, const void *e, z_element_move_f move, size_t element_size, bool use_elem_f) { - if (v->_len == v->_capacity) { + if (v->_capacity == 0) { + *v = _z_svec_make(1, element_size); + } else if (v->_len == v->_capacity) { _Z_RETURN_IF_ERR(_z_svec_expand(v, move, element_size, use_elem_f)); } // Append element diff --git a/src/net/query.c b/src/net/query.c index a4b41b6aa..dcf5b647a 100644 --- a/src/net/query.c +++ b/src/net/query.c @@ -20,15 +20,13 @@ void _z_query_clear_inner(_z_query_t *q) { _z_keyexpr_clear(&q->_key); _z_value_clear(&q->_value); - _z_bytes_drop(&q->attachment); - z_free(q->_parameters); - _z_session_weak_drop(&q->_zn); + _z_bytes_drop(&q->_attachment); + _z_string_clear(&q->_parameters); + _z_session_rc_drop(&q->_zn); } void _z_query_clear(_z_query_t *q) { - // Try to upgrade session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&q->_zn); - if (!_Z_RC_IS_NULL(&sess_rc)) { + if (!_Z_RC_IS_NULL(&q->_zn)) { // Send REPLY_FINAL message _z_zenoh_message_t z_msg = _z_n_msg_make_response_final(q->_request_id); if (_z_send_n_msg(_Z_RC_IN_VAL(&q->_zn), &z_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != @@ -36,7 +34,6 @@ void _z_query_clear(_z_query_t *q) { _Z_ERROR("Query send REPLY_FINAL transport failure !"); } _z_msg_clear(&z_msg); - _z_session_rc_drop(&sess_rc); } // Clean up memory _z_query_clear_inner(q); @@ -46,13 +43,9 @@ z_result_t _z_query_copy(_z_query_t *dst, const _z_query_t *src) { *dst = _z_query_null(); _Z_RETURN_IF_ERR(_z_keyexpr_copy(&dst->_key, &src->_key)); _Z_CLEAN_RETURN_IF_ERR(_z_value_copy(&dst->_value, &src->_value), _z_query_clear_inner(dst)); - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_copy(&dst->attachment, &src->attachment), _z_query_clear_inner(dst)); - dst->_parameters = _z_str_clone(src->_parameters); - if (dst->_parameters == NULL && src->_parameters != NULL) { - _z_query_clear_inner(dst); - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - } - _z_session_weak_copy(&dst->_zn, &src->_zn); + _Z_CLEAN_RETURN_IF_ERR(_z_bytes_copy(&dst->_attachment, &src->_attachment), _z_query_clear_inner(dst)); + _Z_CLEAN_RETURN_IF_ERR(_z_string_copy(&dst->_parameters, &src->_parameters), _z_query_clear_inner(dst)); + _z_session_rc_copy(&dst->_zn, &src->_zn); if (_Z_RC_IS_NULL(&dst->_zn)) { _z_query_clear_inner(dst); return _Z_ERR_SYSTEM_OUT_OF_MEMORY; @@ -73,21 +66,6 @@ void _z_query_free(_z_query_t **query) { } #if Z_FEATURE_QUERYABLE == 1 -_z_query_t _z_query_create(_z_value_t *value, _z_keyexpr_t *key, const _z_slice_t *parameters, _z_session_rc_t *zsrc, - uint32_t request_id, const _z_bytes_t attachment) { - _z_query_t q = _z_query_null(); - q._request_id = request_id; - q._zn = _z_session_rc_clone_as_weak(zsrc); - q._parameters = (char *)z_malloc(parameters->len + 1); - memcpy(q._parameters, parameters->start, parameters->len); - q._parameters[parameters->len] = 0; - q._anyke = (strstr(q._parameters, Z_SELECTOR_QUERY_MATCH) == NULL) ? false : true; - q._key = _z_keyexpr_steal(key); - _z_bytes_copy(&q.attachment, &attachment); - _z_value_move(&q._value, value); - return q; -} - void _z_queryable_clear(_z_queryable_t *qbl) { _z_session_weak_drop(&qbl->_zn); *qbl = _z_queryable_null(); diff --git a/src/net/reply.c b/src/net/reply.c index 67987cb35..9c06b2674 100644 --- a/src/net/reply.c +++ b/src/net/reply.c @@ -39,7 +39,6 @@ void _z_reply_data_free(_z_reply_data_t **reply_data) { } z_result_t _z_reply_data_copy(_z_reply_data_t *dst, const _z_reply_data_t *src) { - *dst = _z_reply_data_init(); if (src->_tag == _Z_REPLY_TAG_DATA) { _Z_RETURN_IF_ERR(_z_sample_copy(&dst->_result.sample, &src->_result.sample)); } else if (src->_tag == _Z_REPLY_TAG_ERROR) { @@ -69,11 +68,7 @@ void _z_reply_free(_z_reply_t **reply) { } } -z_result_t _z_reply_copy(_z_reply_t *dst, const _z_reply_t *src) { - *dst = _z_reply_null(); - _Z_RETURN_IF_ERR(_z_reply_data_copy(&dst->data, &src->data)); - return _Z_RES_OK; -} +z_result_t _z_reply_copy(_z_reply_t *dst, const _z_reply_t *src) { return _z_reply_data_copy(&dst->data, &src->data); } bool _z_pending_reply_eq(const _z_pending_reply_t *one, const _z_pending_reply_t *two) { return one->_tstamp.time == two->_tstamp.time; @@ -87,48 +82,4 @@ void _z_pending_reply_clear(_z_pending_reply_t *pr) { _z_timestamp_clear(&pr->_tstamp); } -_z_reply_t _z_reply_create(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, - const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, - const _z_bytes_t *attachment) { - _z_reply_t reply = _z_reply_null(); - reply.data._tag = _Z_REPLY_TAG_DATA; - reply.data.replier_id = id; - - // Create reply sample - reply.data._result.sample.keyexpr = _z_keyexpr_steal(keyexpr); - reply.data._result.sample.kind = kind; - reply.data._result.sample.timestamp = _z_timestamp_duplicate(timestamp); - _z_bytes_copy(&reply.data._result.sample.payload, payload); - _z_bytes_copy(&reply.data._result.sample.attachment, attachment); - _z_encoding_move(&reply.data._result.sample.encoding, encoding); - - return reply; -} - -_z_reply_t _z_reply_err_create(const _z_bytes_t payload, _z_encoding_t *encoding) { - _z_reply_t reply = _z_reply_null(); - reply.data._tag = _Z_REPLY_TAG_ERROR; - _z_bytes_copy(&reply.data._result.error.payload, &payload); - _z_encoding_move(&reply.data._result.error.encoding, encoding); - return reply; -} -#else -_z_reply_t _z_reply_create(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, - const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, - const _z_bytes_t *attachment) { - _ZP_UNUSED(keyexpr); - _ZP_UNUSED(id); - _ZP_UNUSED(payload); - _ZP_UNUSED(timestamp); - _ZP_UNUSED(encoding); - _ZP_UNUSED(kind); - _ZP_UNUSED(attachment); - return _z_reply_null(); -} - -_z_reply_t _z_reply_err_create(const _z_bytes_t payload, _z_encoding_t *encoding) { - _ZP_UNUSED(payload); - _ZP_UNUSED(encoding); - return _z_reply_null(); -} -#endif +#endif // Z_FEATURE_QUERY == 1 diff --git a/src/net/sample.c b/src/net/sample.c index d158398c6..b700e49c1 100644 --- a/src/net/sample.c +++ b/src/net/sample.c @@ -26,8 +26,8 @@ void _z_sample_move(_z_sample_t *dst, _z_sample_t *src) { void _z_sample_clear(_z_sample_t *sample) { _z_keyexpr_clear(&sample->keyexpr); - _z_bytes_drop(&sample->payload); _z_encoding_clear(&sample->encoding); + _z_bytes_drop(&sample->payload); _z_bytes_drop(&sample->attachment); } @@ -56,32 +56,3 @@ _z_sample_t _z_sample_duplicate(const _z_sample_t *src) { _z_sample_copy(&dst, src); return dst; } - -#if Z_FEATURE_SUBSCRIPTION == 1 -void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, _z_bytes_t *attachment, - z_reliability_t reliability) { - s->kind = kind; - s->qos = qos; - s->reliability = reliability; - s->keyexpr = _z_keyexpr_steal(key); - s->timestamp = _z_timestamp_check(timestamp) ? _z_timestamp_duplicate(timestamp) : _z_timestamp_null(); - _z_encoding_move(&s->encoding, encoding); - _z_bytes_move(&s->attachment, attachment); - _z_bytes_move(&s->payload, payload); -} -#else -void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, _z_bytes_t *attachment, - z_reliability_t reliability) { - _ZP_UNUSED(key); - _ZP_UNUSED(payload); - _ZP_UNUSED(timestamp); - _ZP_UNUSED(encoding); - _ZP_UNUSED(kind); - _ZP_UNUSED(qos); - _ZP_UNUSED(attachment); - _ZP_UNUSED(reliability); - *s = _z_sample_null(); -} -#endif diff --git a/src/net/session.c b/src/net/session.c index cf86220cd..cf3a7e991 100644 --- a/src/net/session.c +++ b/src/net/session.c @@ -95,7 +95,7 @@ z_result_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { _z_hello_list_t *hellos = _z_scout_inner(what, zid, &mcast_locator, timeout, true); if (hellos != NULL) { _z_hello_t *hello = _z_hello_list_head(hellos); - _z_string_svec_copy(&locators, &hello->_locators); + _z_string_svec_copy(&locators, &hello->_locators, true); } _z_hello_list_free(&hellos); } else { @@ -112,7 +112,7 @@ z_result_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { } locators = _z_string_svec_make(1); _z_string_t s = _z_string_copy_from_str(_z_config_get(config, key)); - _z_string_svec_append(&locators, &s); + _z_string_svec_append(&locators, &s, true); } ret = _Z_ERR_SCOUT_NO_RESULTS; diff --git a/src/protocol/codec.c b/src/protocol/codec.c index 64f22cade..eea67422e 100644 --- a/src/protocol/codec.c +++ b/src/protocol/codec.c @@ -194,37 +194,51 @@ z_result_t _z_zsize_decode_with_reader(_z_zint_t *zint, __z_single_byte_reader_t z_result_t _z_uint8_decode_reader(uint8_t *zint, void *context) { return _z_uint8_decode(zint, (_z_zbuf_t *)context); } z_result_t _z_zint64_decode(uint64_t *zint, _z_zbuf_t *zbf) { - return _z_zint64_decode_with_reader(zint, _z_uint8_decode_reader, (void *)zbf); + *zint = 0; + uint8_t b = 0; + _Z_RETURN_IF_ERR(_z_uint8_decode(&b, zbf)); + + uint8_t i = 0; + while (((b & 0x80) != 0) && (i != 7 * (VLE_LEN - 1))) { + *zint = *zint | ((uint64_t)(b & 0x7f)) << i; + _Z_RETURN_IF_ERR(_z_uint8_decode(&b, zbf)); + i = i + (uint8_t)7; + } + *zint = *zint | ((uint64_t)b << i); + return _Z_RES_OK; } z_result_t _z_zint16_decode(uint16_t *zint, _z_zbuf_t *zbf) { - z_result_t ret = _Z_RES_OK; uint64_t buf; _Z_RETURN_IF_ERR(_z_zint64_decode(&buf, zbf)); - if (buf <= UINT16_MAX) { - *zint = (uint16_t)buf; - } else { + if (buf > UINT16_MAX) { _Z_INFO("Invalid zint16 value decoded"); - ret = _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; + return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; } - return ret; + *zint = (uint16_t)buf; + return _Z_RES_OK; } z_result_t _z_zint32_decode(uint32_t *zint, _z_zbuf_t *zbf) { - z_result_t ret = _Z_RES_OK; uint64_t buf; _Z_RETURN_IF_ERR(_z_zint64_decode(&buf, zbf)); - if (buf <= UINT32_MAX) { - *zint = (uint32_t)buf; - } else { + if (buf > UINT32_MAX) { _Z_INFO("Invalid zint32 value decoded"); - ret = _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; + return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; } - return ret; + *zint = (uint32_t)buf; + return _Z_RES_OK; } z_result_t _z_zsize_decode(_z_zint_t *zint, _z_zbuf_t *zbf) { - return _z_zsize_decode_with_reader(zint, _z_uint8_decode_reader, (void *)zbf); + uint64_t buf; + _Z_RETURN_IF_ERR(_z_zint64_decode(&buf, zbf)); + if (buf > SIZE_MAX) { + _Z_INFO("Invalide zsize value decoded"); + return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; + } + *zint = (_z_zint_t)buf; + return _Z_RES_OK; } /*------------------ uint8_array ------------------*/ @@ -281,15 +295,16 @@ z_result_t _z_slice_val_decode(_z_slice_t *bs, _z_zbuf_t *zbf) { return _z_slice z_result_t _z_slice_decode(_z_slice_t *bs, _z_zbuf_t *zbf) { return _z_slice_decode_na(bs, zbf); } -z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf) { +z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf, _z_arc_slice_t *arcs) { // Decode slice _z_slice_t s; _Z_RETURN_IF_ERR(_z_slice_decode(&s, zbf)); // Calc offset size_t offset = _z_ptr_u8_diff(s.start, _Z_RC_IN_VAL(&zbf->_slice)->start); // Get ownership of subslice - _z_arc_slice_t arcs = _z_arc_slice_wrap_slice_rc(&zbf->_slice, offset, s.len); - return _z_bytes_append_slice(bs, &arcs); + *arcs = _z_arc_slice_wrap_slice_rc(&zbf->_slice, offset, s.len); + _z_bytes_alias_arc_slice(bs, arcs); + return _Z_RES_OK; } z_result_t _z_bytes_encode_val(_z_wbuf_t *wbf, const _z_bytes_t *bs) { diff --git a/src/protocol/codec/message.c b/src/protocol/codec/message.c index 35c8fa826..c11c62e46 100644 --- a/src/protocol/codec/message.c +++ b/src/protocol/codec/message.c @@ -327,7 +327,7 @@ z_result_t _z_push_body_decode_extensions(_z_msg_ext_t *extension, void *ctx) { return ret; } -z_result_t _z_push_body_decode(_z_push_body_t *pshb, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_push_body_decode(_z_push_body_t *pshb, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { z_result_t ret = _Z_RES_OK; switch (_Z_MID(header)) { case _Z_MID_Z_PUT: { @@ -342,7 +342,7 @@ z_result_t _z_push_body_decode(_z_push_body_t *pshb, _z_zbuf_t *zbf, uint8_t hea _Z_RETURN_IF_ERR(_z_msg_ext_decode_iter(zbf, _z_push_body_decode_extensions, pshb)); } if (ret == _Z_RES_OK) { - _Z_RETURN_IF_ERR(_z_bytes_decode(&pshb->_body._put._payload, zbf)); + _Z_RETURN_IF_ERR(_z_bytes_decode(&pshb->_body._put._payload, zbf, arcs)); } break; } @@ -367,10 +367,10 @@ z_result_t _z_put_encode(_z_wbuf_t *wbf, const _z_msg_put_t *put) { _z_push_body_t body = {._is_put = true, ._body = {._put = *put}}; return _z_push_body_encode(wbf, &body); } -z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { assert(_Z_MID(header) == _Z_MID_Z_PUT); _z_push_body_t body = {._is_put = true, ._body = {._put = *put}}; - z_result_t ret = _z_push_body_decode(&body, zbf, header); + z_result_t ret = _z_push_body_decode(&body, zbf, header, arcs); *put = body._body._put; return ret; } @@ -382,7 +382,7 @@ z_result_t _z_del_encode(_z_wbuf_t *wbf, const _z_msg_del_t *del) { z_result_t _z_del_decode(_z_msg_del_t *del, _z_zbuf_t *zbf, uint8_t header) { assert(_Z_MID(header) == _Z_MID_Z_DEL); _z_push_body_t body = {._is_put = false, ._body = {._del = *del}}; - z_result_t ret = _z_push_body_decode(&body, zbf, header); + z_result_t ret = _z_push_body_decode(&body, zbf, header, NULL); *del = body._body._del; return ret; } @@ -509,7 +509,7 @@ z_result_t _z_reply_decode_extension(_z_msg_ext_t *extension, void *ctx) { } return ret; } -z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { if (_Z_HAS_FLAG(header, _Z_FLAG_Z_R_C)) { _Z_RETURN_IF_ERR(_z_uint8_decode((uint8_t *)&reply->_consolidation, zbf)); } else { @@ -520,7 +520,7 @@ z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header } uint8_t put_header = 0; _Z_RETURN_IF_ERR(_z_uint8_decode(&put_header, zbf)); - _Z_RETURN_IF_ERR(_z_push_body_decode(&reply->_body, zbf, put_header)); + _Z_RETURN_IF_ERR(_z_push_body_decode(&reply->_body, zbf, put_header, arcs)); return _Z_RES_OK; } @@ -569,14 +569,14 @@ z_result_t _z_err_decode_extension(_z_msg_ext_t *extension, void *ctx) { } return ret; } -z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { if (_Z_HAS_FLAG(header, _Z_FLAG_Z_E_E)) { _Z_RETURN_IF_ERR(_z_encoding_decode(&err->_encoding, zbf)); } if (_Z_HAS_FLAG(header, _Z_FLAG_Z_Z)) { _Z_RETURN_IF_ERR(_z_msg_ext_decode_iter(zbf, _z_err_decode_extension, err)); } - _Z_RETURN_IF_ERR(_z_bytes_decode(&err->_payload, zbf)); + _Z_RETURN_IF_ERR(_z_bytes_decode(&err->_payload, zbf, arcs)); return _Z_RES_OK; } diff --git a/src/protocol/codec/network.c b/src/protocol/codec/network.c index de453c9ae..44cf9cde9 100644 --- a/src/protocol/codec/network.c +++ b/src/protocol/codec/network.c @@ -92,7 +92,7 @@ z_result_t _z_push_decode_ext_cb(_z_msg_ext_t *extension, void *ctx) { return ret; } -z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { z_result_t ret = _Z_RES_OK; msg->_qos = _Z_N_QOS_DEFAULT; ret |= _z_keyexpr_decode(&msg->_key, zbf, _Z_HAS_FLAG(header, _Z_FLAG_N_PUSH_N)); @@ -104,7 +104,7 @@ z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header) if (ret == _Z_RES_OK) { uint8_t msgheader; _Z_RETURN_IF_ERR(_z_uint8_decode(&msgheader, zbf)); - _Z_RETURN_IF_ERR(_z_push_body_decode(&msg->_body, zbf, msgheader)); + _Z_RETURN_IF_ERR(_z_push_body_decode(&msg->_body, zbf, msgheader, arcs)); } return ret; @@ -206,7 +206,7 @@ z_result_t _z_request_decode_extensions(_z_msg_ext_t *extension, void *ctx) { } return _Z_RES_OK; } -z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint8_t header) { +z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint8_t header, _z_arc_slice_t *arcs) { msg->_ext_qos = _Z_N_QOS_DEFAULT; _Z_RETURN_IF_ERR(_z_zsize_decode(&msg->_rid, zbf)); _Z_RETURN_IF_ERR(_z_keyexpr_decode(&msg->_key, zbf, _Z_HAS_FLAG(header, _Z_FLAG_N_REQUEST_N))); @@ -224,7 +224,7 @@ z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint } break; case _Z_MID_Z_PUT: { msg->_tag = _Z_REQUEST_PUT; - _Z_RETURN_IF_ERR(_z_put_decode(&msg->_body._put, zbf, zheader)); + _Z_RETURN_IF_ERR(_z_put_decode(&msg->_body._put, zbf, zheader, arcs)); } break; case _Z_MID_Z_DEL: { msg->_tag = _Z_REQUEST_DEL; @@ -334,7 +334,7 @@ z_result_t _z_response_decode_extension(_z_msg_ext_t *extension, void *ctx) { return ret; } -z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { _Z_DEBUG("Decoding _Z_MID_N_RESPONSE"); msg->_ext_qos = _Z_N_QOS_DEFAULT; z_result_t ret = _Z_RES_OK; @@ -352,12 +352,12 @@ z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t switch (_Z_MID(inner_header)) { case _Z_MID_Z_REPLY: { msg->_tag = _Z_RESPONSE_BODY_REPLY; - ret = _z_reply_decode(&msg->_body._reply, zbf, inner_header); + ret = _z_reply_decode(&msg->_body._reply, zbf, inner_header, arcs); break; } case _Z_MID_Z_ERR: { msg->_tag = _Z_RESPONSE_BODY_ERR; - ret = _z_err_decode(&msg->_body._err, zbf, inner_header); + ret = _z_err_decode(&msg->_body._err, zbf, inner_header, arcs); break; } default: { @@ -513,7 +513,7 @@ z_result_t _z_network_message_encode(_z_wbuf_t *wbf, const _z_network_message_t return _Z_ERR_GENERIC; } } -z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf) { +z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_t *arcs) { uint8_t header; _Z_RETURN_IF_ERR(_z_uint8_decode(&header, zbf)); switch (_Z_MID(header)) { @@ -523,15 +523,15 @@ z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf) } break; case _Z_MID_N_PUSH: { msg->_tag = _Z_N_PUSH; - return _z_push_decode(&msg->_body._push, zbf, header); + return _z_push_decode(&msg->_body._push, zbf, header, arcs); } break; case _Z_MID_N_REQUEST: { msg->_tag = _Z_N_REQUEST; - return _z_request_decode(&msg->_body._request, zbf, header); + return _z_request_decode(&msg->_body._request, zbf, header, arcs); } break; case _Z_MID_N_RESPONSE: { msg->_tag = _Z_N_RESPONSE; - return _z_response_decode(&msg->_body._response, zbf, header); + return _z_response_decode(&msg->_body._response, zbf, header, arcs); } break; case _Z_MID_N_RESPONSE_FINAL: { msg->_tag = _Z_N_RESPONSE_FINAL; diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index f09b5460f..5e07d5fea 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -28,10 +28,6 @@ #include "zenoh-pico/utils/logging.h" #include "zenoh-pico/utils/result.h" -#define _Z_FRAME_VEC_BASE_SIZE 8 // Abritrary small value -#define _Z_FRAME_VEC_SIZE_FROM_ZBUF_LEN(len) \ - (_Z_FRAME_VEC_BASE_SIZE + (len) / Z_CONFIG_FRAME_AVG_MSG_SIZE) // Approximate number of messages in frame - uint8_t _z_whatami_to_uint8(z_whatami_t whatami) { return (whatami >> 1) & 0x03; // get set bit index; only first 3 bits can be set } @@ -225,7 +221,7 @@ z_result_t _z_init_decode(_z_t_msg_init_t *msg, _z_zbuf_t *zbf, uint8_t header) if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_INIT_A) == true)) { ret |= _z_slice_decode(&msg->_cookie, zbf); } else { - msg->_cookie = _z_slice_empty(); + msg->_cookie = _z_slice_null(); } if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_Z) == true)) { @@ -270,10 +266,10 @@ z_result_t _z_open_decode(_z_t_msg_open_t *msg, _z_zbuf_t *zbf, uint8_t header) if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_OPEN_A) == false)) { ret |= _z_slice_decode(&msg->_cookie, zbf); if (ret != _Z_RES_OK) { - msg->_cookie = _z_slice_empty(); + msg->_cookie = _z_slice_null(); } } else { - msg->_cookie = _z_slice_empty(); + msg->_cookie = _z_slice_null(); } if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_Z) == true)) { ret |= _z_msg_ext_skip_non_mandatories(zbf, 0x02); @@ -352,7 +348,50 @@ z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_ return ret; } -z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header) { +static void _z_frame_update_arcs_msg_pool(_z_network_message_svec_t *msg_pool, _z_arc_slice_svec_t *arc_pool) { + for (size_t i = 0; i < arc_pool->_len; i++) { + _z_network_message_t *nm = _z_network_message_svec_get(msg_pool, i); + switch (nm->_tag) { + case _Z_N_PUSH: { + if (!nm->_body._push._body._is_put) { + continue; + } + _z_bytes_alias_arc_slice(&nm->_body._push._body._body._put._payload, + _z_arc_slice_svec_get(arc_pool, i)); + } break; + case _Z_N_REQUEST: { + if (nm->_body._request._tag != _Z_REQUEST_PUT) { + continue; + } + _z_bytes_alias_arc_slice(&nm->_body._request._body._put._payload, _z_arc_slice_svec_get(arc_pool, i)); + } break; + case _Z_N_RESPONSE: { + switch (nm->_body._response._tag) { + case _Z_RESPONSE_BODY_REPLY: + if (!nm->_body._response._body._reply._body._is_put) { + continue; + } + _z_bytes_alias_arc_slice(&nm->_body._response._body._reply._body._body._put._payload, + _z_arc_slice_svec_get(arc_pool, i)); + break; + + case _Z_RESPONSE_BODY_ERR: + _z_bytes_alias_arc_slice(&nm->_body._response._body._err._payload, + _z_arc_slice_svec_get(arc_pool, i)); + break; + + default: + continue; + } + } + default: + continue; + } + } +} + +z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool) { z_result_t ret = _Z_RES_OK; *msg = (_z_t_msg_frame_t){0}; @@ -360,26 +399,32 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header if (_Z_HAS_FLAG(header, _Z_FLAG_T_Z)) { _Z_RETURN_IF_ERR(_z_msg_ext_skip_non_mandatories(zbf, 0x04)); } - // Create message vector - size_t var_size = _Z_FRAME_VEC_SIZE_FROM_ZBUF_LEN(_z_zbuf_len(zbf)); - msg->_messages = _z_network_message_svec_make(var_size); - if (msg->_messages._capacity == 0) { - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - } - _z_network_message_svec_init(&msg->_messages); + // Init message vector + msg_pool->_len = 0; + arc_pool->_len = 0; + _z_network_message_svec_init(msg_pool, 0); size_t msg_idx = 0; while (_z_zbuf_len(zbf) > 0) { // Expand message vector if needed - if (msg_idx >= msg->_messages._capacity) { - _Z_RETURN_IF_ERR(_z_network_message_svec_expand(&msg->_messages)); - _z_network_message_svec_init(&msg->_messages); + if (msg_idx >= msg_pool->_capacity) { + _Z_RETURN_IF_ERR(_z_network_message_svec_expand(msg_pool, false)); + _z_network_message_svec_init(msg_pool, msg_pool->_len); + } + // Expand arc pool if needed + if (msg_idx >= arc_pool->_capacity) { + _Z_RETURN_IF_ERR(_z_arc_slice_svec_expand(arc_pool, false)); + // Update arcs references in msg pool + _z_frame_update_arcs_msg_pool(msg_pool, arc_pool); } // Mark the reading position of the iobfer size_t r_pos = _z_zbuf_get_rpos(zbf); - _z_network_message_t *nm = _z_network_message_svec_get_mut(&msg->_messages, msg_idx); - ret = _z_network_message_decode(nm, zbf); + // Retrieve storage in resource pool + _z_network_message_t *nm = _z_network_message_svec_get_mut(msg_pool, msg_idx); + _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(arc_pool, msg_idx); + // Decode message + ret = _z_network_message_decode(nm, zbf, arcs); if (ret != _Z_RES_OK) { - _z_network_message_svec_clear(&msg->_messages); + _z_network_message_svec_reset(msg_pool); _z_zbuf_set_rpos(zbf, r_pos); // Restore the reading position of the iobfer // FIXME: Check for the return error, since not all of them means a decoding error @@ -391,9 +436,12 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header } return ret; } - msg->_messages._len++; + arc_pool->_len++; + msg_pool->_len++; msg_idx++; } + // Alias network message svec in frame struct + msg->_messages = _z_network_message_svec_alias(msg_pool); return _Z_RES_OK; } @@ -493,7 +541,8 @@ z_result_t _z_transport_message_encode(_z_wbuf_t *wbf, const _z_transport_messag return ret; } -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf) { +z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool) { z_result_t ret = _Z_RES_OK; ret |= _z_uint8_decode(&msg->_header, zbf); // Decode the header @@ -501,7 +550,7 @@ z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *z uint8_t mid = _Z_MID(msg->_header); switch (mid) { case _Z_MID_T_FRAME: { - ret |= _z_frame_decode(&msg->_body._frame, zbf, msg->_header); + ret |= _z_frame_decode(&msg->_body._frame, zbf, msg->_header, arc_pool, msg_pool); } break; case _Z_MID_T_FRAGMENT: { ret |= _z_fragment_decode(&msg->_body._fragment, zbf, msg->_header); diff --git a/src/protocol/core.c b/src/protocol/core.c index 16842f708..da1ef9ef8 100644 --- a/src/protocol/core.c +++ b/src/protocol/core.c @@ -63,7 +63,7 @@ z_result_t _z_value_copy(_z_value_t *dst, const _z_value_t *src) { z_result_t _z_hello_copy(_z_hello_t *dst, const _z_hello_t *src) { *dst = _z_hello_null(); - _Z_RETURN_IF_ERR(_z_string_svec_copy(&dst->_locators, &src->_locators)); + _Z_RETURN_IF_ERR(_z_string_svec_copy(&dst->_locators, &src->_locators, true)); dst->_version = src->_version; dst->_whatami = src->_whatami; memcpy(&dst->_zid.id, &src->_zid.id, _Z_ID_LEN); diff --git a/src/protocol/definitions/message.c b/src/protocol/definitions/message.c index 0c3058e0a..e8f967e62 100644 --- a/src/protocol/definitions/message.c +++ b/src/protocol/definitions/message.c @@ -23,8 +23,7 @@ void _z_msg_reply_clear(_z_msg_reply_t *msg) { _z_push_body_clear(&msg->_body); } void _z_msg_put_clear(_z_msg_put_t *msg) { - // TODO: systematically move everything so there's nothing to clear - _z_bytes_drop(&msg->_payload); + _z_bytes_aliased_drop(&msg->_payload); _z_bytes_drop(&msg->_attachment); _z_encoding_clear(&msg->_encoding); _z_timestamp_clear(&msg->_commons._timestamp); @@ -45,5 +44,5 @@ void _z_msg_query_clear(_z_msg_query_t *msg) { } void _z_msg_err_clear(_z_msg_err_t *err) { _z_encoding_clear(&err->_encoding); - _z_bytes_drop(&err->_payload); + _z_bytes_aliased_drop(&err->_payload); } diff --git a/src/protocol/definitions/transport.c b/src/protocol/definitions/transport.c index 448951e46..fa910b771 100644 --- a/src/protocol/definitions/transport.c +++ b/src/protocol/definitions/transport.c @@ -40,7 +40,7 @@ void _z_t_msg_close_clear(_z_t_msg_close_t *msg) { (void)(msg); } void _z_t_msg_keep_alive_clear(_z_t_msg_keep_alive_t *msg) { (void)(msg); } -void _z_t_msg_frame_clear(_z_t_msg_frame_t *msg) { _z_network_message_svec_clear(&msg->_messages); } +void _z_t_msg_frame_clear(_z_t_msg_frame_t *msg) { (void)(msg); } void _z_t_msg_fragment_clear(_z_t_msg_fragment_t *msg) { _z_slice_clear(&msg->_payload); } @@ -248,7 +248,7 @@ _z_transport_message_t _z_t_msg_make_frame_header(_z_zint_t sn, z_reliability_t /*------------------ Fragment Message ------------------*/ _z_transport_message_t _z_t_msg_make_fragment_header(_z_zint_t sn, z_reliability_t reliability, bool is_last) { - return _z_t_msg_make_fragment(sn, _z_slice_empty(), reliability, is_last); + return _z_t_msg_make_fragment(sn, _z_slice_null(), reliability, is_last); } _z_transport_message_t _z_t_msg_make_fragment(_z_zint_t sn, _z_slice_t payload, z_reliability_t reliability, bool is_last) { @@ -307,7 +307,7 @@ void _z_t_msg_copy_keep_alive(_z_t_msg_keep_alive_t *clone, _z_t_msg_keep_alive_ void _z_t_msg_copy_frame(_z_t_msg_frame_t *clone, _z_t_msg_frame_t *msg) { clone->_sn = msg->_sn; - _z_network_message_svec_copy(&clone->_messages, &msg->_messages); + _z_network_message_svec_copy(&clone->_messages, &msg->_messages, false); } /*------------------ Transport Message ------------------*/ diff --git a/src/protocol/keyexpr.c b/src/protocol/keyexpr.c index f71e38875..15e1beee0 100644 --- a/src/protocol/keyexpr.c +++ b/src/protocol/keyexpr.c @@ -82,7 +82,6 @@ void _z_keyexpr_clear(_z_keyexpr_t *rk) { if (_z_keyexpr_has_suffix(rk)) { _z_string_clear(&rk->_suffix); } - rk->_suffix = _z_string_null(); } void _z_keyexpr_free(_z_keyexpr_t **rk) { @@ -103,7 +102,15 @@ bool _z_keyexpr_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { if (_z_keyexpr_mapping_id(left) != _z_keyexpr_mapping_id(right)) { return false; } - return _z_string_equals(&left->_suffix, &right->_suffix); + bool l_suffix = _z_keyexpr_has_suffix(left); + bool r_suffix = _z_keyexpr_has_suffix(right); + if (l_suffix != r_suffix) { + return false; + } + if (l_suffix && r_suffix) { + return _z_string_equals(&left->_suffix, &right->_suffix); + } + return true; } _z_keyexpr_t _z_keyexpr_alias_from_user_defined(_z_keyexpr_t src, bool try_declared) { diff --git a/src/session/query.c b/src/session/query.c index 241839551..22f05571c 100644 --- a/src/session/query.c +++ b/src/session/query.c @@ -111,39 +111,38 @@ z_result_t _z_register_pending_query(_z_session_t *zn, _z_pending_query_t *pen_q return ret; } -z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, const _z_keyexpr_t keyexpr, - _z_msg_put_t *msg, z_sample_kind_t kind) { - z_result_t ret = _Z_RES_OK; - +static z_result_t _z_trigger_query_reply_partial_inner(_z_session_t *zn, const _z_zint_t id, + const _z_keyexpr_t *keyexpr, _z_msg_put_t *msg, + z_sample_kind_t kind) { _z_session_mutex_lock(zn); + // Get query infos _z_pending_query_t *pen_qry = __unsafe__z_get_pending_query_by_id(zn, id); - if ((ret == _Z_RES_OK) && (pen_qry == NULL)) { - ret = _Z_ERR_ENTITY_UNKNOWN; + if (pen_qry == NULL) { + _z_session_mutex_unlock(zn); + return _Z_ERR_ENTITY_UNKNOWN; } - - _z_keyexpr_t expanded_ke = __unsafe_z_get_expanded_key_from_key(zn, &keyexpr, true); - if ((ret == _Z_RES_OK) && - ((pen_qry->_anykey == false) && (_z_keyexpr_suffix_intersects(&pen_qry->_key, &keyexpr) == false))) { - ret = _Z_ERR_QUERY_NOT_MATCH; + _z_keyexpr_t expanded_ke = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); + if (!pen_qry->_anykey && !_z_keyexpr_suffix_intersects(&pen_qry->_key, keyexpr)) { + _z_session_mutex_unlock(zn); + return _Z_ERR_QUERY_NOT_MATCH; } - // Build the reply - _z_reply_t reply = _z_reply_create(&expanded_ke, zn->_local_zid, &msg->_payload, &msg->_commons._timestamp, - &msg->_encoding, kind, &msg->_attachment); - - bool drop = false; - // Verify if this is a newer reply, free the old one in case it is - if ((ret == _Z_RES_OK) && ((pen_qry->_consolidation == Z_CONSOLIDATION_MODE_LATEST) || - (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC))) { + _z_reply_t reply = _z_reply_alias(&expanded_ke, zn->_local_zid, &msg->_payload, &msg->_commons._timestamp, + &msg->_encoding, kind, &msg->_attachment); + // Process monotonic & latest consolidation mode + if ((pen_qry->_consolidation == Z_CONSOLIDATION_MODE_LATEST) || + (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC)) { + bool drop = false; _z_pending_reply_list_t *pen_rps = pen_qry->_pending_replies; _z_pending_reply_t *pen_rep = NULL; + + // Verify if this is a newer reply, free the old one in case it is while (pen_rps != NULL) { pen_rep = _z_pending_reply_list_head(pen_rps); - // Check if this is the same resource key if (_z_string_equals(&pen_rep->_reply.data._result.sample.keyexpr._suffix, - &reply.data._result.sample.keyexpr._suffix) == true) { + &reply.data._result.sample.keyexpr._suffix)) { if (msg->_commons._timestamp.time <= pen_rep->_tstamp.time) { drop = true; } else { @@ -154,87 +153,74 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, } pen_rps = _z_pending_reply_list_tail(pen_rps); } - - if (drop == false) { + if (!drop) { // Cache most recent reply pen_rep = (_z_pending_reply_t *)z_malloc(sizeof(_z_pending_reply_t)); - if (pen_rep != NULL) { - if (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC) { - // No need to store the whole reply in the monotonic mode. - _z_reply_t partial_reply; - (void)memset(&partial_reply, 0, - sizeof(_z_reply_t)); // Avoid warnings on uninitialized values on the reply - partial_reply.data._tag = _Z_REPLY_TAG_DATA; - partial_reply.data._result.sample.keyexpr = - _z_keyexpr_duplicate(&reply.data._result.sample.keyexpr); - pen_rep->_reply = partial_reply; - } else { - pen_rep->_reply = reply; // Store the whole reply in the latest mode - } - pen_rep->_tstamp = _z_timestamp_duplicate(&msg->_commons._timestamp); - pen_qry->_pending_replies = _z_pending_reply_list_push(pen_qry->_pending_replies, pen_rep); + if (pen_rep == NULL) { + return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + } + if (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC) { + // No need to store the whole reply in the monotonic mode. + pen_rep->_reply = _z_reply_null(); + pen_rep->_reply.data._tag = _Z_REPLY_TAG_DATA; + pen_rep->_reply.data._result.sample.keyexpr = _z_keyexpr_duplicate(&reply.data._result.sample.keyexpr); } else { - ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; + // Copy the reply to store it out of context + _Z_RETURN_IF_ERR(_z_reply_copy(&pen_rep->_reply, &reply)); } + pen_rep->_tstamp = _z_timestamp_duplicate(&msg->_commons._timestamp); + pen_qry->_pending_replies = _z_pending_reply_list_push(pen_qry->_pending_replies, pen_rep); } } - _z_session_mutex_unlock(zn); - // Trigger the user callback - if ((ret == _Z_RES_OK) && (pen_qry->_consolidation != Z_CONSOLIDATION_MODE_LATEST)) { - _z_reply_t cb_reply = _z_reply_null(); - cb_reply = _z_reply_move(&reply); - pen_qry->_callback(&cb_reply, pen_qry->_arg); - _z_reply_clear(&cb_reply); - return ret; - } - // Other cases - if (drop || (ret != _Z_RES_OK)) { - _z_reply_clear(&reply); + // Trigger callback if applicable + if (pen_qry->_consolidation != Z_CONSOLIDATION_MODE_LATEST) { + pen_qry->_callback(&reply, pen_qry->_arg); } + return _Z_RES_OK; +} +z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, _z_keyexpr_t *keyexpr, + _z_msg_put_t *msg, z_sample_kind_t kind) { + z_result_t ret = _z_trigger_query_reply_partial_inner(zn, id, keyexpr, msg, kind); + // Clean up + _z_keyexpr_clear(keyexpr); + _z_bytes_aliased_drop(&msg->_payload); + _z_bytes_drop(&msg->_attachment); + _z_encoding_clear(&msg->_encoding); return ret; } z_result_t _z_trigger_query_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *msg) { z_result_t ret = _Z_RES_OK; + // Retrieve query _z_session_mutex_lock(zn); - _z_pending_query_t *pen_qry = __unsafe__z_get_pending_query_by_id(zn, id); - if ((ret == _Z_RES_OK) && (pen_qry == NULL)) { + if (pen_qry == NULL) { ret = _Z_ERR_ENTITY_UNKNOWN; } - - // Build the reply - _z_reply_t reply = _z_reply_err_create(msg->_payload, &msg->_encoding); - _z_session_mutex_unlock(zn); // Trigger the user callback if (ret == _Z_RES_OK) { - _z_reply_t cb_reply = _z_reply_null(); - cb_reply = _z_reply_move(&reply); - pen_qry->_callback(&cb_reply, pen_qry->_arg); - _z_reply_clear(&cb_reply); + _z_reply_t reply = _z_reply_err_alias(&msg->_payload, &msg->_encoding); + pen_qry->_callback(&reply, pen_qry->_arg); } - - if (ret != _Z_RES_OK) { - _z_reply_clear(&reply); - } - + // Clean up + _z_bytes_aliased_drop(&msg->_payload); + _z_encoding_clear(&msg->_encoding); return ret; } z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id) { z_result_t ret = _Z_RES_OK; + // Retrieve query _z_session_mutex_lock(zn); - - // Final reply received for unknown query id _z_pending_query_t *pen_qry = __unsafe__z_get_pending_query_by_id(zn, id); - if ((ret == _Z_RES_OK) && (pen_qry == NULL)) { + if (pen_qry == NULL) { ret = _Z_ERR_ENTITY_UNKNOWN; } // The reply is the final one, apply consolidation if needed @@ -243,21 +229,15 @@ z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id) { _z_pending_reply_t *pen_rep = _z_pending_reply_list_head(pen_qry->_pending_replies); // Trigger the query handler - _z_reply_t cb_reply = _z_reply_null(); - cb_reply = _z_reply_move(&pen_rep->_reply); - pen_qry->_callback(&cb_reply, pen_qry->_arg); + pen_qry->_callback(&pen_rep->_reply, pen_qry->_arg); pen_qry->_pending_replies = _z_pending_reply_list_pop(pen_qry->_pending_replies, NULL); - _z_reply_clear(&cb_reply); } } - if (ret == _Z_RES_OK) { // Dropping a pending query triggers the dropper callback that is now the equivalent to a reply with the FINAL zn->_pending_queries = _z_pending_query_list_drop_filter(zn->_pending_queries, _z_pending_query_eq, pen_qry); } - _z_session_mutex_unlock(zn); - return ret; } diff --git a/src/session/queryable.c b/src/session/queryable.c index ba04debd7..d3b120751 100644 --- a/src/session/queryable.c +++ b/src/session/queryable.c @@ -25,8 +25,63 @@ #include "zenoh-pico/session/resource.h" #include "zenoh-pico/session/utils.h" #include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/pointers.h" +#include "zenoh-pico/utils/string.h" #if Z_FEATURE_QUERYABLE == 1 + +#define _Z_QLEINFOS_VEC_SIZE 4 // Arbitrary initial size + +#if Z_FEATURE_RX_CACHE == 1 +static inline bool _z_queryable_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, + _z_queryable_infos_svec_t *infos_val, size_t *qle_nb) { + if (!_z_keyexpr_equals(ke, &zn->_queryable_cache.ke_in)) { + return false; + } + *ke_val = _z_keyexpr_alias(zn->_queryable_cache.ke_out); + *infos_val = _z_queryable_infos_svec_alias(&zn->_queryable_cache.infos); + *qle_nb = zn->_queryable_cache.qle_nb; + return true; +} + +static inline void _z_queryable_update_cache(_z_session_t *zn, const _z_keyexpr_t *ke_in, const _z_keyexpr_t *ke_out, + _z_queryable_infos_svec_t *infos) { + // Clear previous data + _z_queryable_cache_clear(&zn->_queryable_cache); + // Register new info + zn->_queryable_cache.ke_in = _z_keyexpr_duplicate(ke_in); + zn->_queryable_cache.ke_out = _z_keyexpr_duplicate(ke_out); + zn->_queryable_cache.infos = _z_queryable_infos_svec_alias(infos); + zn->_queryable_cache.qle_nb = _z_queryable_infos_svec_len(infos); +} + +void _z_queryable_cache_clear(_z_queryable_cache_t *cache) { + _z_queryable_infos_svec_clear(&cache->infos); + _z_keyexpr_clear(&cache->ke_in); + _z_keyexpr_clear(&cache->ke_out); +} + +#else +static inline bool _z_queryable_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, + _z_queryable_infos_svec_t *infos_val, size_t *sub_nb) { + _ZP_UNUSED(zn); + _ZP_UNUSED(ke); + _ZP_UNUSED(ke_val); + _ZP_UNUSED(infos_val); + _ZP_UNUSED(sub_nb); + return false; +} + +static inline void _z_queryable_update_cache(_z_session_t *zn, const _z_keyexpr_t *ke_in, const _z_keyexpr_t *ke_out, + _z_queryable_infos_svec_t *infos) { + _ZP_UNUSED(zn); + _ZP_UNUSED(ke_in); + _ZP_UNUSED(ke_out); + _ZP_UNUSED(infos); + return; +} +#endif // Z_FEATURE_RX_CACHE == 1 + bool _z_session_queryable_eq(const _z_session_queryable_t *one, const _z_session_queryable_t *two) { return one->_id == two->_id; } @@ -39,7 +94,8 @@ void _z_session_queryable_clear(_z_session_queryable_t *qle) { } /*------------------ Queryable ------------------*/ -_z_session_queryable_rc_t *__z_get_session_queryable_by_id(_z_session_queryable_rc_list_t *qles, const _z_zint_t id) { +static _z_session_queryable_rc_t *__z_get_session_queryable_by_id(_z_session_queryable_rc_list_t *qles, + const _z_zint_t id) { _z_session_queryable_rc_t *ret = NULL; _z_session_queryable_rc_list_t *xs = qles; @@ -56,29 +112,12 @@ _z_session_queryable_rc_t *__z_get_session_queryable_by_id(_z_session_queryable_ return ret; } -_z_session_queryable_rc_list_t *__z_get_session_queryable_by_key(_z_session_queryable_rc_list_t *qles, - const _z_keyexpr_t key) { - _z_session_queryable_rc_list_t *ret = NULL; - - _z_session_queryable_rc_list_t *xs = qles; - while (xs != NULL) { - _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); - if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(qle)->_key, &key) == true) { - ret = _z_session_queryable_rc_list_push(ret, _z_session_queryable_rc_clone_as_ptr(qle)); - } - - xs = _z_session_queryable_rc_list_tail(xs); - } - - return ret; -} - /** * This function is unsafe because it operates in potentially concurrent data. * Make sure that the following mutexes are locked before calling this function: * - zn->_mutex_inner */ -_z_session_queryable_rc_t *__unsafe_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id) { +static _z_session_queryable_rc_t *__unsafe_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id) { _z_session_queryable_rc_list_t *qles = zn->_local_queryable; return __z_get_session_queryable_by_id(qles, id); } @@ -88,9 +127,23 @@ _z_session_queryable_rc_t *__unsafe_z_get_session_queryable_by_id(_z_session_t * * Make sure that the following mutexes are locked before calling this function: * - zn->_mutex_inner */ -_z_session_queryable_rc_list_t *__unsafe_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t key) { +static z_result_t __unsafe_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t *key, + _z_queryable_infos_svec_t *qle_infos) { _z_session_queryable_rc_list_t *qles = zn->_local_queryable; - return __z_get_session_queryable_by_key(qles, key); + + *qle_infos = _z_queryable_infos_svec_make(_Z_QLEINFOS_VEC_SIZE); + _z_session_queryable_rc_list_t *xs = qles; + while (xs != NULL) { + // Parse queryable list + _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); + if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(qle)->_key, key)) { + _z_queryable_infos_t new_qle_info = {.arg = _Z_RC_IN_VAL(qle)->_arg, + .callback = _Z_RC_IN_VAL(qle)->_callback}; + _Z_RETURN_IF_ERR(_z_queryable_infos_svec_append(qle_infos, &new_qle_info, false)); + } + xs = _z_session_queryable_rc_list_tail(xs); + } + return _Z_RES_OK; } _z_session_queryable_rc_t *_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id) { @@ -103,17 +156,6 @@ _z_session_queryable_rc_t *_z_get_session_queryable_by_id(_z_session_t *zn, cons return qle; } -_z_session_queryable_rc_list_t *_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t *keyexpr) { - _z_session_mutex_lock(zn); - - _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, false); - _z_session_queryable_rc_list_t *qles = __unsafe_z_get_session_queryable_by_key(zn, key); - - _z_session_mutex_unlock(zn); - - return qles; -} - _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_session_queryable_t *q) { _Z_DEBUG(">>> Allocating queryable for (%ju:%.*s)", (uintmax_t)q->_key._id, (int)_z_string_len(&q->_key._suffix), _z_string_data(&q->_key._suffix)); @@ -132,37 +174,79 @@ _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_se return ret; } -z_result_t _z_trigger_queryables(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, const _z_keyexpr_t q_key, uint32_t qid, - const _z_bytes_t attachment) { - z_result_t ret = _Z_RES_OK; - _z_session_t *zn = _Z_RC_IN_VAL(zsrc); - - _z_session_mutex_lock(zn); - - _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, &q_key, true); - if (_z_keyexpr_has_suffix(&key)) { - _z_session_queryable_rc_list_t *qles = __unsafe_z_get_session_queryable_by_key(zn, key); - +static z_result_t _z_session_queryable_get_infos(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_keyexpr_t *key, + _z_queryable_infos_svec_t *qles, size_t *qle_nb) { + // Check cache + if (!_z_queryable_get_from_cache(zn, keyexpr, key, qles, qle_nb)) { + _Z_DEBUG("Resolving %d - %.*s on mapping 0x%x", keyexpr->_id, (int)_z_string_len(&keyexpr->_suffix), + _z_string_data(&keyexpr->_suffix), _z_keyexpr_mapping_id(keyexpr)); + _z_session_mutex_lock(zn); + *key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); + + if (!_z_keyexpr_has_suffix(key)) { + _z_session_mutex_unlock(zn); + return _Z_ERR_KEYEXPR_UNKNOWN; + } + // Get queryable list + z_result_t ret = __unsafe_z_get_session_queryable_by_key(zn, key, qles); _z_session_mutex_unlock(zn); + if (ret != _Z_RES_OK) { + return ret; + } + *qle_nb = _z_queryable_infos_svec_len(qles); + // Update cache + _z_queryable_update_cache(zn, keyexpr, key, qles); + } + return _Z_RES_OK; +} - // Build the z_query - _z_query_t q = _z_query_create(&msgq->_ext_value, &key, &msgq->_parameters, zsrc, qid, attachment); - _z_query_rc_t query = _z_query_rc_new_from_val(&q); - // Parse session_queryable list - _z_session_queryable_rc_list_t *xs = qles; - while (xs != NULL) { - _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); - _Z_RC_IN_VAL(qle)->_callback(&query, _Z_RC_IN_VAL(qle)->_arg); - xs = _z_session_queryable_rc_list_tail(xs); +static z_result_t _z_trigger_queryables_inner(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, const _z_keyexpr_t *q_key, + uint32_t qid) { + _z_session_t *zn = _Z_RC_IN_VAL(zsrc); + _z_keyexpr_t key; + _z_queryable_infos_svec_t qles; + size_t qle_nb; + // Retrieve sub infos + _Z_RETURN_IF_ERR(_z_session_queryable_get_infos(zn, q_key, &key, &qles, &qle_nb)); + // Check if there are queryables + _Z_DEBUG("Triggering %ju queryables for key %d - %.*s", (uintmax_t)qle_nb, key._id, + (int)_z_string_len(&key._suffix), _z_string_data(&key._suffix)); + if (qle_nb == 0) { + _z_keyexpr_clear(&key); + return _Z_RES_OK; + } + // Check anyke + char *slice_end = _z_ptr_char_offset((char *)msgq->_parameters.start, (ptrdiff_t)msgq->_parameters.len); + bool anyke = false; + if (_z_slice_check(&msgq->_parameters)) { + if (_z_strstr((char *)msgq->_parameters.start, slice_end, Z_SELECTOR_QUERY_MATCH) != NULL) { + anyke = true; } - // Clean up - _z_query_rc_drop(&query); - _z_session_queryable_rc_list_free(&qles); - } else { - _z_session_mutex_unlock(zn); - ret = _Z_ERR_KEYEXPR_UNKNOWN; } + // Build the z_query + _z_query_t query = + _z_query_alias(&msgq->_ext_value, &key, &msgq->_parameters, zsrc, qid, &msgq->_ext_attachment, anyke); + // Parse session_queryable svec + for (size_t i = 0; i < qle_nb; i++) { + _z_queryable_infos_t *qle_info = _z_queryable_infos_svec_get(&qles, i); + qle_info->callback(&query, qle_info->arg); + } + // Clean up + _z_keyexpr_clear(&key); +#if Z_FEATURE_RX_CACHE != 1 + _z_queryable_infos_svec_release(&qles); // Otherwise it's released with cache +#endif + return _Z_RES_OK; +} +z_result_t _z_trigger_queryables(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, _z_keyexpr_t *q_key, uint32_t qid) { + z_result_t ret = _z_trigger_queryables_inner(zsrc, msgq, q_key, qid); + // Clean up + _z_keyexpr_clear(q_key); + _z_encoding_clear(&msgq->_ext_value.encoding); + _z_bytes_drop(&msgq->_ext_value.payload); + _z_bytes_drop(&msgq->_ext_attachment); + _z_slice_clear(&msgq->_parameters); return ret; } diff --git a/src/session/reply.c b/src/session/reply.c index 7eb13194c..6361099ee 100644 --- a/src/session/reply.c +++ b/src/session/reply.c @@ -19,7 +19,7 @@ #include "zenoh-pico/session/query.h" #include "zenoh-pico/utils/logging.h" -z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t key, _z_msg_reply_t *reply) { +z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t *key, _z_msg_reply_t *reply) { z_result_t ret = _Z_RES_OK; // TODO check id to know where to dispatch diff --git a/src/session/rx.c b/src/session/rx.c index 70213b898..c15e53810 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -93,8 +93,7 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * case _Z_REQUEST_QUERY: { #if Z_FEATURE_QUERYABLE == 1 _z_msg_query_t *query = &req->_body._query; - ret = _z_trigger_queryables(zsrc, query, req->_key, (uint32_t)req->_rid, - req->_body._query._ext_attachment); + ret = _z_trigger_queryables(zsrc, query, &req->_key, (uint32_t)req->_rid); #else _Z_DEBUG("_Z_REQUEST_QUERY dropped, queryables not supported"); #endif @@ -133,7 +132,7 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * switch (response->_tag) { case _Z_RESPONSE_BODY_REPLY: { _z_msg_reply_t *reply = &response->_body._reply; - ret = _z_trigger_reply_partial(zn, response->_request_id, response->_key, reply); + ret = _z_trigger_reply_partial(zn, response->_request_id, &response->_key, reply); } break; case _Z_RESPONSE_BODY_ERR: { _z_msg_err_t *error = &response->_body._err; diff --git a/src/session/scout.c b/src/session/scout.c index 28244f08f..5badf7201 100644 --- a/src/session/scout.c +++ b/src/session/scout.c @@ -89,7 +89,7 @@ _z_hello_list_t *__z_scout_loop(const _z_wbuf_t *wbf, _z_string_t *locator, unsi for (size_t i = 0; i < n_loc; i++) { _z_string_t s = _z_locator_to_string(&s_msg._body._hello._locators._val[i]); - _z_string_svec_append(&hello->_locators, &s); + _z_string_svec_append(&hello->_locators, &s, true); } } else { // @TODO: construct the locator departing from the sock address diff --git a/src/session/subscription.c b/src/session/subscription.c index 3e6297176..cad4821a5 100644 --- a/src/session/subscription.c +++ b/src/session/subscription.c @@ -34,12 +34,13 @@ #if Z_FEATURE_RX_CACHE == 1 static inline bool _z_subscription_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, - _z_subscription_infos_svec_t *infos_val) { + _z_subscription_infos_svec_t *infos_val, size_t *sub_nb) { if (!_z_keyexpr_equals(ke, &zn->_subscription_cache.ke_in)) { return false; } *ke_val = _z_keyexpr_alias(zn->_subscription_cache.ke_out); *infos_val = _z_subscription_infos_svec_alias(&zn->_subscription_cache.infos); + *sub_nb = zn->_subscription_cache.sub_nb; return true; } @@ -51,6 +52,7 @@ static inline void _z_subscription_update_cache(_z_session_t *zn, const _z_keyex zn->_subscription_cache.ke_in = _z_keyexpr_duplicate(ke_in); zn->_subscription_cache.ke_out = _z_keyexpr_duplicate(ke_out); zn->_subscription_cache.infos = _z_subscription_infos_svec_alias(infos); + zn->_subscription_cache.sub_nb = _z_subscription_infos_svec_len(infos); } void _z_subscription_cache_clear(_z_subscription_cache_t *cache) { @@ -61,11 +63,12 @@ void _z_subscription_cache_clear(_z_subscription_cache_t *cache) { #else static inline bool _z_subscription_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, - _z_subscription_infos_svec_t *infos_val) { + _z_subscription_infos_svec_t *infos_val, size_t *sub_nb) { _ZP_UNUSED(zn); _ZP_UNUSED(ke); _ZP_UNUSED(ke_val); _ZP_UNUSED(infos_val); + _ZP_UNUSED(sub_nb); return false; } @@ -137,7 +140,7 @@ static z_result_t __unsafe_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(sub)->_key, key)) { _z_subscription_infos_t new_sub_info = {.arg = _Z_RC_IN_VAL(sub)->_arg, .callback = _Z_RC_IN_VAL(sub)->_callback}; - _Z_RETURN_IF_ERR(_z_subscription_infos_svec_append(sub_infos, &new_sub_info)); + _Z_RETURN_IF_ERR(_z_subscription_infos_svec_append(sub_infos, &new_sub_info, false)); } xs = _z_subscription_rc_list_tail(xs); } @@ -176,7 +179,7 @@ _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_loca return ret; } -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +void _z_trigger_local_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, _z_bytes_t *attachment, z_reliability_t reliability) { z_result_t ret = _z_trigger_subscriptions(zn, keyexpr, payload, encoding, Z_SAMPLE_KIND_PUT, timestamp, qos, @@ -184,54 +187,76 @@ void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexp (void)ret; } -z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, - _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, - const _z_n_qos_t qos, _z_bytes_t *attachment, z_reliability_t reliability) { - _z_sample_t sample; - _z_keyexpr_t key; - _z_subscription_infos_svec_t subs; +static z_result_t _z_subscription_get_infos(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_keyexpr_t *key, + _z_subscription_infos_svec_t *subs, size_t *sub_nb) { // Check cache - if (!_z_subscription_get_from_cache(zn, keyexpr, &key, &subs)) { + if (!_z_subscription_get_from_cache(zn, keyexpr, key, subs, sub_nb)) { _Z_DEBUG("Resolving %d - %.*s on mapping 0x%x", keyexpr->_id, (int)_z_string_len(&keyexpr->_suffix), _z_string_data(&keyexpr->_suffix), _z_keyexpr_mapping_id(keyexpr)); _z_session_mutex_lock(zn); - key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); + *key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); - if (!_z_keyexpr_has_suffix(&key)) { + if (!_z_keyexpr_has_suffix(key)) { _z_session_mutex_unlock(zn); return _Z_ERR_KEYEXPR_UNKNOWN; } // Get subscription list - z_result_t ret = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, &key, &subs); + z_result_t ret = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, key, subs); _z_session_mutex_unlock(zn); if (ret != _Z_RES_OK) { return ret; } + *sub_nb = _z_subscription_infos_svec_len(subs); // Update cache - _z_subscription_update_cache(zn, keyexpr, &key, &subs); + _z_subscription_update_cache(zn, keyexpr, key, subs); } - // Check if there is subs - size_t sub_nb = _z_subscription_infos_svec_len(&subs); + return _Z_RES_OK; +} + +static z_result_t _z_trigger_subscriptions_inner(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, + _z_encoding_t *encoding, const _z_zint_t kind, + const _z_timestamp_t *timestamp, const _z_n_qos_t qos, + _z_bytes_t *attachment, z_reliability_t reliability) { + _z_keyexpr_t key; + _z_subscription_infos_svec_t subs; + size_t sub_nb; + // Retrieve sub infos + _Z_RETURN_IF_ERR(_z_subscription_get_infos(zn, keyexpr, &key, &subs, &sub_nb)); + // Check if there are subs _Z_DEBUG("Triggering %ju subs for key %d - %.*s", (uintmax_t)sub_nb, key._id, (int)_z_string_len(&key._suffix), _z_string_data(&key._suffix)); if (sub_nb == 0) { + _z_keyexpr_clear(&key); return _Z_RES_OK; } - // Build the sample - _z_sample_create(&sample, &key, payload, timestamp, encoding, kind, qos, attachment, reliability); + // Create sample + _z_sample_t sample = _z_sample_alias(&key, payload, timestamp, encoding, kind, qos, attachment, reliability); // Parse subscription infos svec for (size_t i = 0; i < sub_nb; i++) { _z_subscription_infos_t *sub_info = _z_subscription_infos_svec_get(&subs, i); sub_info->callback(&sample, sub_info->arg); } // Clean up - _z_sample_clear(&sample); + _z_keyexpr_clear(&key); #if Z_FEATURE_RX_CACHE != 1 _z_subscription_infos_svec_release(&subs); // Otherwise it's released with cache #endif return _Z_RES_OK; } +z_result_t _z_trigger_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, + _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, _z_bytes_t *attachment, z_reliability_t reliability) { + z_result_t ret = + _z_trigger_subscriptions_inner(zn, keyexpr, payload, encoding, kind, timestamp, qos, attachment, reliability); + // Clean up + _z_keyexpr_clear(keyexpr); + _z_encoding_clear(encoding); + _z_bytes_aliased_drop(payload); + _z_bytes_drop(attachment); + return ret; +} + void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub) { _z_session_mutex_lock(zn); @@ -256,7 +281,7 @@ void _z_flush_subscriptions(_z_session_t *zn) { } #else // Z_FEATURE_SUBSCRIPTION == 0 -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +void _z_trigger_local_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, _z_bytes_t *attachment, z_reliability_t reliability) { _ZP_UNUSED(zn); diff --git a/src/session/utils.c b/src/session/utils.c index dde52129c..84ad8793e 100644 --- a/src/session/utils.c +++ b/src/session/utils.c @@ -26,6 +26,8 @@ #include "zenoh-pico/utils/logging.h" /*------------------ clone helpers ------------------*/ +void _z_timestamp_copy(_z_timestamp_t *dst, const _z_timestamp_t *src) { *dst = *src; } + _z_timestamp_t _z_timestamp_duplicate(const _z_timestamp_t *tstamp) { return *tstamp; } void _z_timestamp_move(_z_timestamp_t *dst, _z_timestamp_t *src) { @@ -66,6 +68,9 @@ z_result_t _z_session_init(_z_session_rc_t *zsrc, _z_id_t *zid) { #endif #if Z_FEATURE_QUERYABLE == 1 zn->_local_queryable = NULL; +#if Z_FEATURE_RX_CACHE == 1 + memset(&zn->_queryable_cache, 0, sizeof(zn->_queryable_cache)); +#endif #endif #if Z_FEATURE_QUERY == 1 zn->_pending_queries = NULL; @@ -120,6 +125,9 @@ void _z_session_clear(_z_session_t *zn) { #endif #if Z_FEATURE_QUERYABLE == 1 _z_flush_session_queryable(zn); +#if Z_FEATURE_RX_CACHE == 1 + _z_queryable_cache_clear(&zn->_queryable_cache); +#endif #endif #if Z_FEATURE_QUERY == 1 _z_flush_pending_queries(zn); diff --git a/src/transport/common/rx.c b/src/transport/common/rx.c index 5c5c68073..49a39b6cb 100644 --- a/src/transport/common/rx.c +++ b/src/transport/common/rx.c @@ -72,10 +72,14 @@ z_result_t _z_link_recv_t_msg(_z_transport_message_t *t_msg, const _z_link_t *zl } if (ret == _Z_RES_OK) { _z_transport_message_t l_t_msg; - ret = _z_transport_message_decode(&l_t_msg, &zbf); + _z_arc_slice_svec_t arc_pool = _z_arc_slice_svec_make(1); + _z_network_message_svec_t msg_pool = _z_network_message_svec_make(1); + ret = _z_transport_message_decode(&l_t_msg, &zbf, &arc_pool, &msg_pool); if (ret == _Z_RES_OK) { _z_t_msg_copy(t_msg, &l_t_msg); } + _z_arc_slice_svec_clear(&arc_pool); + _z_network_message_svec_clear(&msg_pool); } _z_zbuf_clear(&zbf); diff --git a/src/transport/multicast/read.c b/src/transport/multicast/read.c index ad7a1eb1c..bea0b82f3 100644 --- a/src/transport/multicast/read.c +++ b/src/transport/multicast/read.c @@ -107,7 +107,8 @@ void *_zp_multicast_read_task(void *ztm_arg) { while (_z_zbuf_len(&zbuf) > 0) { // Decode one session message _z_transport_message_t t_msg; - z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf); + z_result_t ret = + _z_transport_message_decode(&t_msg, &zbuf, &ztm->_common._arc_pool, &ztm->_common._msg_pool); if (ret == _Z_RES_OK) { ret = _z_multicast_handle_transport_message(ztm, &t_msg, &addr); diff --git a/src/transport/multicast/rx.c b/src/transport/multicast/rx.c index c1f438c38..1ab13f161 100644 --- a/src/transport/multicast/rx.c +++ b/src/transport/multicast/rx.c @@ -77,7 +77,7 @@ static z_result_t _z_multicast_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_t if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode: %ju", (uintmax_t)_z_zbuf_len(&ztm->_common._zbuf)); - ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf); + ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool, &ztm->_common._msg_pool); } _z_transport_rx_mutex_unlock(&ztm->_common); return ret; @@ -240,7 +240,9 @@ z_result_t _z_multicast_handle_transport_message(_z_transport_multicast_t *ztm, } // Decode message _z_zenoh_message_t zm = {0}; - ret = _z_network_message_decode(&zm, &zbf); + assert(ztm->_common._arc_pool._capacity >= 1); + _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(&ztm->_common._arc_pool, 0); + ret = _z_network_message_decode(&zm, &zbf, arcs); zm._reliability = tmsg_reliability; if (ret == _Z_RES_OK) { uint16_t mapping = entry->_peer_id; diff --git a/src/transport/multicast/transport.c b/src/transport/multicast/transport.c index 776d007fb..3f5f1c1bf 100644 --- a/src/transport/multicast/transport.c +++ b/src/transport/multicast/transport.c @@ -81,8 +81,13 @@ z_result_t _z_multicast_transport_create(_z_transport_t *zt, _z_link_t *zl, ztm->_common._wbuf = _z_wbuf_make(mtu, false); ztm->_common._zbuf = _z_zbuf_make(Z_BATCH_MULTICAST_SIZE); + // Initialize resource pool + ztm->_common._arc_pool = _z_arc_slice_svec_make(_Z_RES_POOL_INIT_SIZE); + ztm->_common._msg_pool = _z_network_message_svec_make(_Z_RES_POOL_INIT_SIZE); + // Clean up the buffers if one of them failed to be allocated - if ((_z_wbuf_capacity(&ztm->_common._wbuf) != mtu) || + if ((ztm->_common._msg_pool._capacity == 0) || (ztm->_common._arc_pool._capacity == 0) || + (_z_wbuf_capacity(&ztm->_common._wbuf) != mtu) || (_z_zbuf_capacity(&ztm->_common._zbuf) != Z_BATCH_MULTICAST_SIZE)) { ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; _Z_ERROR("Not enough memory to allocate transport tx rx buffers!"); @@ -209,6 +214,8 @@ void _z_multicast_transport_clear(_z_transport_t *zt) { // Clean up the buffers _z_wbuf_clear(&ztm->_common._wbuf); _z_zbuf_clear(&ztm->_common._zbuf); + _z_arc_slice_svec_release(&ztm->_common._arc_pool); + _z_network_message_svec_release(&ztm->_common._msg_pool); // Clean up peer list _z_transport_peer_entry_list_free(&ztm->_peers); diff --git a/src/transport/raweth/rx.c b/src/transport/raweth/rx.c index 389b57c70..fdec282f8 100644 --- a/src/transport/raweth/rx.c +++ b/src/transport/raweth/rx.c @@ -100,7 +100,7 @@ z_result_t _z_raweth_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_transport_m // Decode message if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode: %ju", (uintmax_t)_z_zbuf_len(&ztm->_common._zbuf)); - ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf); + ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool, &ztm->_common._msg_pool); } _z_transport_rx_mutex_unlock(&ztm->_common); return ret; diff --git a/src/transport/unicast/read.c b/src/transport/unicast/read.c index ab347251d..5851f3146 100644 --- a/src/transport/unicast/read.c +++ b/src/transport/unicast/read.c @@ -102,7 +102,8 @@ void *_zp_unicast_read_task(void *ztu_arg) { while (_z_zbuf_len(&zbuf) > 0) { // Decode one session message _z_transport_message_t t_msg; - z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf); + z_result_t ret = + _z_transport_message_decode(&t_msg, &zbuf, &ztu->_common._arc_pool, &ztu->_common._msg_pool); if (ret == _Z_RES_OK) { ret = _z_unicast_handle_transport_message(ztu, &t_msg); diff --git a/src/transport/unicast/rx.c b/src/transport/unicast/rx.c index 1d30e988f..628f2815d 100644 --- a/src/transport/unicast/rx.c +++ b/src/transport/unicast/rx.c @@ -75,7 +75,7 @@ z_result_t _z_unicast_recv_t_msg_na(_z_transport_unicast_t *ztu, _z_transport_me if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode"); - ret = _z_transport_message_decode(t_msg, &ztu->_common._zbuf); + ret = _z_transport_message_decode(t_msg, &ztu->_common._zbuf, &ztu->_common._arc_pool, &ztu->_common._msg_pool); // Mark the session that we have received data if (ret == _Z_RES_OK) { @@ -194,7 +194,9 @@ z_result_t _z_unicast_handle_transport_message(_z_transport_unicast_t *ztu, _z_t } // Decode message _z_zenoh_message_t zm = {0}; - ret = _z_network_message_decode(&zm, &zbf); + assert(ztu->_common._arc_pool._capacity >= 1); + _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(&ztu->_common._arc_pool, 0); + ret = _z_network_message_decode(&zm, &zbf, arcs); zm._reliability = tmsg_reliability; if (ret == _Z_RES_OK) { _z_handle_network_message(ztu->_common._session, &zm, _Z_KEYEXPR_MAPPING_UNKNOWN_REMOTE); diff --git a/src/transport/unicast/transport.c b/src/transport/unicast/transport.c index fe48e3f24..6f90b4397 100644 --- a/src/transport/unicast/transport.c +++ b/src/transport/unicast/transport.c @@ -64,8 +64,13 @@ z_result_t _z_unicast_transport_create(_z_transport_t *zt, _z_link_t *zl, ztu->_common._wbuf = _z_wbuf_make(wbuf_size, false); ztu->_common._zbuf = _z_zbuf_make(zbuf_size); + // Initialize resources pool + ztu->_common._arc_pool = _z_arc_slice_svec_make(_Z_RES_POOL_INIT_SIZE); + ztu->_common._msg_pool = _z_network_message_svec_make(_Z_RES_POOL_INIT_SIZE); + // Clean up the buffers if one of them failed to be allocated - if ((_z_wbuf_capacity(&ztu->_common._wbuf) != wbuf_size) || + if ((ztu->_common._msg_pool._capacity == 0) || (ztu->_common._arc_pool._capacity == 0) || + (_z_wbuf_capacity(&ztu->_common._wbuf) != wbuf_size) || (_z_zbuf_capacity(&ztu->_common._zbuf) != zbuf_size)) { ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; _Z_ERROR("Not enough memory to allocate transport tx rx buffers!"); @@ -227,7 +232,7 @@ static z_result_t _z_unicast_handshake_listener(_z_transport_unicast_establish_p } _Z_DEBUG("Received Z_INIT(Syn)"); // Encode InitAck - _z_slice_t cookie = _z_slice_empty(); + _z_slice_t cookie = _z_slice_null(); _z_transport_message_t iam = _z_t_msg_make_init_ack(whatami, *local_zid, cookie); // Any of the size parameters in the InitAck must be less or equal than the one in the InitSyn, if (iam._body._init._seq_num_res > tmsg._body._init._seq_num_res) { @@ -339,6 +344,8 @@ void _z_unicast_transport_clear(_z_transport_t *zt) { // Clean up the buffers _z_wbuf_clear(&ztu->_common._wbuf); _z_zbuf_clear(&ztu->_common._zbuf); + _z_arc_slice_svec_release(&ztu->_common._arc_pool); + _z_network_message_svec_release(&ztu->_common._msg_pool); #if Z_FEATURE_FRAGMENTATION == 1 _z_wbuf_clear(&ztu->_dbuf_reliable); _z_wbuf_clear(&ztu->_dbuf_best_effort); diff --git a/tests/modularity.py b/tests/modularity.py index 7350ae70a..be18d86c1 100644 --- a/tests/modularity.py +++ b/tests/modularity.py @@ -47,8 +47,8 @@ def pub_and_sub(args): # Expected z_sub output & status if args.sub == 1: - z_sub_expected_status = -2 if args.pub == 1: + z_sub_expected_status = [0, -2] z_sub_expected_output = """Opening session... Declaring Subscriber on 'demo/example/**'... Press CTRL-C to quit... @@ -63,16 +63,17 @@ def pub_and_sub(args): >> [Subscriber] Received ('demo/example/zenoh-pico-pub': '[ 8] Pub from Pico!') >> [Subscriber] Received ('demo/example/zenoh-pico-pub': '[ 9] Pub from Pico!')""" else: + z_sub_expected_status = [-2] z_sub_expected_output = """Opening session... Declaring Subscriber on 'demo/example/**'... Press CTRL-C to quit...""" else: - z_sub_expected_status = 254 + z_sub_expected_status = [254] z_sub_expected_output = "ERROR: Zenoh pico was compiled without " "Z_FEATURE_SUBSCRIPTION but this example requires it." print("Start subscriber") # Start z_sub in the background - z_sub_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_sub" + z_sub_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_sub -n 10" z_sub_process = subprocess.Popen( z_sub_command, shell=True, @@ -132,7 +133,7 @@ def pub_and_sub(args): print("Check subscriber status & output") # Check the exit status of z_sub z_sub_status = z_sub_process.returncode - if z_sub_status == z_sub_expected_status: + if z_sub_status in z_sub_expected_status: print("z_sub status valid") else: print(f"z_sub status invalid, expected: {z_sub_expected_status}, received: {z_sub_status}") @@ -175,24 +176,25 @@ def query_and_queryable(args): # Expected z_queryable output & status if args.queryable == 1: - z_queryable_expected_status = -2 if args.query == 1: + z_queryable_expected_status = [0, -2] z_queryable_expected_output = """Opening session... Creating Queryable on 'demo/example/zenoh-pico-queryable'... Press CTRL-C to quit... >> [Queryable handler] Received Query 'demo/example/**' """ else: + z_queryable_expected_status = [-2] z_queryable_expected_output = """Opening session... Creating Queryable on 'demo/example/zenoh-pico-queryable'... Press CTRL-C to quit...""" else: - z_queryable_expected_status = 254 + z_queryable_expected_status = [254] z_queryable_expected_output = "ERROR: Zenoh pico was compiled without " "Z_FEATURE_QUERYABLE but this example requires it." print("Start queryable") # Start z_queryable in the background - z_queryable_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_queryable" + z_queryable_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_queryable -n 1" z_queryable_process = subprocess.Popen( z_queryable_command, shell=True, @@ -252,7 +254,7 @@ def query_and_queryable(args): print("Check queryable status & output") # Check the exit status of z_queryable z_queryable_status = z_queryable_process.returncode - if z_queryable_status == z_queryable_expected_status: + if z_queryable_status in z_queryable_expected_status: print("z_queryable status valid") else: print(f"z_queryable status invalid, expected: {z_queryable_expected_status}," f" received: {z_queryable_status}") diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index f3a92a77a..1b0b134c5 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -172,7 +172,7 @@ _z_wbuf_t gen_wbuf(size_t len) { _z_slice_t gen_slice(size_t len) { if (len == 0) { - return _z_slice_empty(); + return _z_slice_null(); } uint8_t *p = (uint8_t *)z_malloc(sizeof(uint8_t) * len); @@ -225,7 +225,7 @@ _z_string_svec_t gen_str_array(size_t size) { _z_string_svec_t sa = _z_string_svec_make(size); for (size_t i = 0; i < size; i++) { _z_string_t s = _z_string_copy_from_str(gen_str(16)); - _z_string_svec_append(&sa, &s); + _z_string_svec_append(&sa, &s, true); } return sa; @@ -555,7 +555,8 @@ void payload_field(void) { _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); _z_bytes_t d_pld = _z_bytes_null(); - res = _z_bytes_decode(&d_pld, &zbf); + _z_arc_slice_t arcs = {0}; + res = _z_bytes_decode(&d_pld, &zbf, &arcs); assert(res == _Z_RES_OK); printf(" "); assert_eq_bytes(&e_pld, &d_pld); @@ -563,7 +564,7 @@ void payload_field(void) { // Free _z_bytes_drop(&e_pld); - _z_bytes_drop(&d_pld); + _z_bytes_aliased_drop(&d_pld); _z_zbuf_clear(&zbf); _z_wbuf_clear(&wbf); } @@ -1068,7 +1069,8 @@ void declare_message(void) { // Decode _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); _z_network_message_t d_dcl = {0}; - res = _z_network_message_decode(&d_dcl, &zbf); + _z_arc_slice_t arcs = {0}; + res = _z_network_message_decode(&d_dcl, &zbf, &arcs); assert(res == _Z_RES_OK); assert_eq_declare_message(&n_msg._body._declare, &d_dcl._body._declare); @@ -1202,8 +1204,9 @@ void push_body_message(void) { // Decode _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); _z_push_body_t d_da = {0}; + _z_arc_slice_t arcs = {0}; uint8_t header = _z_zbuf_read(&zbf); - res = _z_push_body_decode(&d_da, &zbf, header); + res = _z_push_body_decode(&d_da, &zbf, header, &arcs); assert(res == _Z_RES_OK); assert_eq_push_body(&e_da, &d_da); @@ -1269,9 +1272,10 @@ void err_message(void) { _z_msg_err_t expected = gen_err(); assert(_z_err_encode(&wbf, &expected) == _Z_RES_OK); _z_msg_err_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_err_decode(&decoded, &zbf, header)); + assert(_Z_RES_OK == _z_err_decode(&decoded, &zbf, header, &arcs)); assert_eq_err(&expected, &decoded); _z_msg_err_clear(&decoded); _z_msg_err_clear(&expected); @@ -1297,9 +1301,10 @@ void reply_message(void) { _z_msg_reply_t expected = gen_reply(); assert(_z_reply_encode(&wbf, &expected) == _Z_RES_OK); _z_msg_reply_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_reply_decode(&decoded, &zbf, header)); + assert(_Z_RES_OK == _z_reply_decode(&decoded, &zbf, header, &arcs)); assert_eq_reply(&expected, &decoded); _z_msg_reply_clear(&decoded); _z_msg_reply_clear(&expected); @@ -1329,9 +1334,10 @@ void push_message(void) { _z_n_msg_push_t expected = gen_push(); assert(_z_push_encode(&wbf, &expected) == _Z_RES_OK); _z_n_msg_push_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_push_decode(&decoded, &zbf, header)); + assert(_Z_RES_OK == _z_push_decode(&decoded, &zbf, header, &arcs)); assert_eq_push(&expected, &decoded); _z_n_msg_push_clear(&decoded); _z_n_msg_push_clear(&expected); @@ -1399,9 +1405,10 @@ void request_message(void) { _z_n_msg_request_t expected = gen_request(); assert(_z_request_encode(&wbf, &expected) == _Z_RES_OK); _z_n_msg_request_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - z_result_t ret = _z_request_decode(&decoded, &zbf, header); + z_result_t ret = _z_request_decode(&decoded, &zbf, header, &arcs); assert(_Z_RES_OK == ret); assert_eq_request(&expected, &decoded); _z_n_msg_request_clear(&decoded); @@ -1457,9 +1464,10 @@ void response_message(void) { _z_n_msg_response_t expected = gen_response(); assert(_z_response_encode(&wbf, &expected) == _Z_RES_OK); _z_n_msg_response_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - z_result_t ret = _z_response_decode(&decoded, &zbf, header); + z_result_t ret = _z_response_decode(&decoded, &zbf, header, &arcs); assert(_Z_RES_OK == ret); assert_eq_response(&expected, &decoded); _z_n_msg_response_clear(&decoded); @@ -1715,8 +1723,10 @@ void frame_message(void) { _z_transport_message_t expected = gen_frame(); assert(_z_frame_encode(&wbf, expected._header, &expected._body._frame) == _Z_RES_OK); _z_t_msg_frame_t decoded = {0}; + _z_arc_slice_svec_t arcs = _z_arc_slice_svec_make(1); + _z_network_message_svec_t msg = _z_network_message_svec_make(1); _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - z_result_t ret = _z_frame_decode(&decoded, &zbf, expected._header); + z_result_t ret = _z_frame_decode(&decoded, &zbf, expected._header, &arcs, &msg); assert(_Z_RES_OK == ret); assert_eq_frame(&expected._body._frame, &decoded); _z_t_msg_frame_clear(&decoded); @@ -1808,8 +1818,10 @@ void transport_message(void) { _z_transport_message_t expected = gen_transport(); assert(_z_transport_message_encode(&wbf, &expected) == _Z_RES_OK); _z_transport_message_t decoded = {0}; + _z_arc_slice_svec_t arcs = _z_arc_slice_svec_make(1); + _z_network_message_svec_t msg = _z_network_message_svec_make(1); _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - z_result_t ret = _z_transport_message_decode(&decoded, &zbf); + z_result_t ret = _z_transport_message_decode(&decoded, &zbf, &arcs, &msg); assert(_Z_RES_OK == ret); assert_eq_transport(&expected, &decoded); _z_t_msg_clear(&decoded);