Skip to content

Commit

Permalink
added z_keyexpr_relation_to
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisBiryukov91 committed Jul 9, 2024
1 parent 7f36277 commit 4a453c4
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 16 deletions.
3 changes: 3 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ Primitives
.. autocfunction:: primitives.h::zp_keyexpr_intersect_null_terminated
.. autocfunction:: primitives.h::z_keyexpr_equals
.. autocfunction:: primitives.h::zp_keyexpr_equals_null_terminated
.. autocfunction:: primitives.h::z_keyexpr_relation_to
.. autocfunction:: primitives.h::z_keyexpr_concat
.. autocfunction:: primitives.h::z_keyexpr_join
.. autocfunction:: primitives.h::z_config_new
.. autocfunction:: primitives.h::z_config_default
.. autocfunction:: primitives.h::zp_config_get
Expand Down
16 changes: 16 additions & 0 deletions include/zenoh-pico/api/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ typedef enum {
Z_KEYEXPR_CANON_CONTAINS_UNBOUND_DOLLAR = -8
} zp_keyexpr_canon_status_t;

/**
* Intersection level of 2 key expressions.
*
* Enumerators:
* Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT: 2 key expression do not intersect.
* Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS: 2 key expressions intersect, i.e. there exists at least one key expression
* that is included by both. Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES: First key expression is the superset of second one.
* Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS: 2 key expressions are equal.
*/
typedef enum {
Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0,
Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1,
Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2,
Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3,
} z_keyexpr_intersection_level_t;

/**
* Sample kind values.
*
Expand Down
31 changes: 23 additions & 8 deletions include/zenoh-pico/api/primitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ int8_t z_keyexpr_as_view_string(const z_loaned_keyexpr_t *keyexpr, z_view_string
* Constructs key expression by concatenation of key expression in `left` with a string in `right`.
* Returns 0 in case of success, negative error code otherwise.
*
* To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation,
* as this would extremely likely cause bugs.
*
* To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this
* operation, as this would extremely likely cause bugs.
*
* Parameters:
* keyexpr: Pointer to an uninitialized :c:type:`z_owned_keyexpr_t` to store the keyexpr.
* left: Pointer to :c:type:`z_loaned_keyexpr_t` to keyexpr to concatenate to.
Expand All @@ -145,12 +145,12 @@ int8_t z_keyexpr_as_view_string(const z_loaned_keyexpr_t *keyexpr, z_view_string
* Return:
* ``0`` if creation successful, ``negative value`` otherwise.
*/
int8_t z_keyexpr_concat(z_owned_keyexpr_t* key, const z_loaned_keyexpr_t *left, const char* right, size_t len);
int8_t z_keyexpr_concat(z_owned_keyexpr_t *key, const z_loaned_keyexpr_t *left, const char *right, size_t len);

/**
* Constructs key expression by performing path-joining (automatically inserting '/'). The resulting key expression is automatically
* canonized.
*
* Constructs key expression by performing path-joining (automatically inserting '/'). The resulting key expression is
* automatically canonized.
*
* Parameters:
* keyexpr: Pointer to an uninitialized :c:type:`z_owned_keyexpr_t` to store the keyexpr.
* left: Pointer to :c:type:`z_loaned_keyexpr_t` to the left part of resulting key expression.
Expand All @@ -159,7 +159,22 @@ int8_t z_keyexpr_concat(z_owned_keyexpr_t* key, const z_loaned_keyexpr_t *left,
* Return:
* ``0`` if creation successful, ``negative value`` otherwise.
*/
int8_t z_keyexpr_join(z_owned_keyexpr_t* key, const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right);
int8_t z_keyexpr_join(z_owned_keyexpr_t *key, const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right);

/**
* Returns the relation between `left` and `right` from `left`'s point of view.
*
* Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for
* most applications.
*
* Parameters:
* left: Pointer to :c:type:`z_loaned_keyexpr_t` representing left key expression.
* right: Pointer to :c:type:`z_loaned_keyexpr_t` representing right key expression.
*
* Return:
* Relation between `left` and `right` from `left`'s point of view.
*/
z_keyexpr_intersection_level_t z_keyexpr_relation_to(const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right);

/**
* Builds a null-terminated string from a :c:type:`z_loaned_keyexpr_t` for a given
Expand Down
21 changes: 14 additions & 7 deletions src/api/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,38 +111,38 @@ int8_t z_keyexpr_as_view_string(const z_loaned_keyexpr_t *keyexpr, z_view_string
return ret;
}

int8_t z_keyexpr_concat(z_owned_keyexpr_t* key, const z_loaned_keyexpr_t *left, const char* right, size_t len) {
int8_t z_keyexpr_concat(z_owned_keyexpr_t *key, const z_loaned_keyexpr_t *left, const char *right, size_t len) {
z_keyexpr_null(key);
if (len == 0) {
return z_keyexpr_clone(key, left);
} else if (right == NULL) {
return _Z_ERR_INVALID;
}
}
size_t left_len = strlen(left->_suffix);
if (left_len == 0) return _Z_ERR_INVALID;
if (left->_suffix[left_len - 1] == '*' && right[0] == '*') {
return _Z_ERR_INVALID;
}
char* s = z_malloc(left_len + len + 1);

char *s = z_malloc(left_len + len + 1);
if (s == NULL) return _Z_ERR_SYSTEM_OUT_OF_MEMORY;
s[left_len + len] = '\0';

memcpy(s, left->_suffix, left_len);
memcpy(s + left_len, right, len);

key->_val = _z_rname(s);
_z_keyexpr_set_owns_suffix(&key->_val, true);
return _Z_RES_OK;
}

int8_t z_keyexpr_join(z_owned_keyexpr_t* key, const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right) {
int8_t z_keyexpr_join(z_owned_keyexpr_t *key, const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right) {
z_keyexpr_null(key);

size_t left_len = strlen(left->_suffix);
size_t right_len = strlen(right->_suffix);

char* s = z_malloc(left_len + right_len + 2);
char *s = z_malloc(left_len + right_len + 2);
if (s == NULL) return _Z_ERR_SYSTEM_OUT_OF_MEMORY;
s[left_len + right_len + 1] = '\0';
s[left_len] = '/';
Expand All @@ -155,6 +155,13 @@ int8_t z_keyexpr_join(z_owned_keyexpr_t* key, const z_loaned_keyexpr_t *left, co
return _Z_RES_OK;
}

z_keyexpr_intersection_level_t z_keyexpr_relation_to(const z_loaned_keyexpr_t *left, const z_loaned_keyexpr_t *right) {
if (z_keyexpr_equals(left, right)) return Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS;
if (z_keyexpr_includes(left, right)) return Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES;
if (z_keyexpr_intersects(left, right)) return Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS;
return Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT;
}

int8_t zp_keyexpr_resolve(const z_loaned_session_t *zs, const z_loaned_keyexpr_t *keyexpr, z_owned_string_t *str) {
_z_keyexpr_t ekey = _z_get_expanded_key_from_key(&_Z_RC_IN_VAL(zs), keyexpr);
str->_val = _z_string_make((char *)ekey._suffix); // ekey will be out of scope so
Expand Down
19 changes: 18 additions & 1 deletion tests/z_keyexpr_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,28 @@ void test_join(void) {

assert(0 == z_keyexpr_join(&ke3, z_keyexpr_loan(&ke1), z_keyexpr_loan(&ke2)));
assert(keyexpr_equals_string(z_keyexpr_loan(&ke3), "a/*/**/d/e/c"));

z_keyexpr_drop(z_keyexpr_move(&ke1));
z_keyexpr_drop(z_keyexpr_move(&ke2));
z_keyexpr_drop(z_keyexpr_move(&ke3));
}

void test_relation_to(void) {
z_view_keyexpr_t foobar, foostar, barstar;
z_view_keyexpr_from_str(&foobar, "foo/bar");
z_view_keyexpr_from_str(&foostar, "foo/*");
z_view_keyexpr_from_str(&barstar, "bar/*");

assert(z_keyexpr_relation_to(z_view_keyexpr_loan(&foostar), z_view_keyexpr_loan(&foobar)) ==
Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES);
assert(z_keyexpr_relation_to(z_view_keyexpr_loan(&foobar), z_view_keyexpr_loan(&foostar)) ==
Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS);
assert(z_keyexpr_relation_to(z_view_keyexpr_loan(&foostar), z_view_keyexpr_loan(&foostar)) ==
Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS);
assert(z_keyexpr_relation_to(z_view_keyexpr_loan(&barstar), z_view_keyexpr_loan(&foobar)) ==
Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT);
}

int main(void) {
test_intersects();
test_includes();
Expand All @@ -501,6 +517,7 @@ int main(void) {
test_keyexpr_constructor();
test_concat();
test_join();
test_relation_to();

return 0;
}

0 comments on commit 4a453c4

Please sign in to comment.