From 1c3cc767899b018972e1580018f18899da7d988c Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sat, 5 Dec 2020 13:32:48 +0300 Subject: [PATCH] override rb_find by adding compare func in this way, custom compare can be used for getting items. For instance you can compare null terminated string with non-null terminated string by providing custom compare to find() --- include/ds/rb.h | 39 +++++++++++++++++++++++++++++++++++---- src/rb.c | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/include/ds/rb.h b/include/ds/rb.h index e5cb24e..9bc8fed 100644 --- a/include/ds/rb.h +++ b/include/ds/rb.h @@ -139,8 +139,7 @@ rb_remove(RBTree *tree, */ DS_EXPORT void* -rb_find(RBTree *tree, - void *key); +rb_find(RBTree * __restrict tree, void * __restrict key); /*! * @brief find node by key. It returns RBnode you can get value from node @@ -152,8 +151,40 @@ rb_find(RBTree *tree, */ DS_EXPORT RBNode* -rb_find_node(RBTree *tree, - void *key); +rb_find_node(RBTree * __restrict tree, void * __restrict key); + +/*! + * @brief find value by key with cmp + * + * for instance you can compare null-terminated string key with non-null + * terminated string by providing cmp func for find + * + * @param[in] tree rbtree + * @param[in] key key + * + * @return found value or NULL + */ +DS_EXPORT +void* +rb_find_by(RBTree * __restrict tree, void * __restrict key, const DsCmpFn cmp); + +/*! + * @brief find node by key with cmp. + * It returns RBnode you can get value from node + * + * for instance you can compare null-terminated string key with non-null + * terminated string by providing cmp func for find + * + * @param[in] tree rbtree + * @param[in] key key + * + * @return found RBNode or NULL + */ +DS_EXPORT +RBNode* +rb_find_node_by(RBTree * __restrict tree, + void * __restrict key, + const DsCmpFn cmp); /*! * @brief get parent node of found node (of key). This will lookup for node diff --git a/src/rb.c b/src/rb.c index a3c44ef..eecda3e 100644 --- a/src/rb.c +++ b/src/rb.c @@ -541,9 +541,9 @@ rb_remove(RBTree *tree, void *key) { DS_EXPORT void* -rb_find(RBTree *tree, void *key) { +rb_find(RBTree * __restrict tree, void * __restrict key) { RBNode *found; - found = rb_find_node(tree, key); + found = rb_find_node_by(tree, key, tree->cmp); if (found == NULL) return NULL; @@ -552,15 +552,37 @@ rb_find(RBTree *tree, void *key) { DS_EXPORT RBNode* -rb_find_node(RBTree *tree, void *key) { - RBNode *iter; +rb_find_node(RBTree * __restrict tree, void * __restrict key) { + return rb_find_node_by(tree, key, tree->cmp); +} - iter = tree->root->chld[RB_RIGHT]; +DS_EXPORT +void* +rb_find_by(RBTree * __restrict tree, + void * __restrict key, + const DsCmpFn cmp) { + RBNode *found; + found = rb_find_node_by(tree, key, cmp); + if (found == NULL) + return NULL; - while (iter != tree->nullNode) { + return found->val; +} + +DS_EXPORT +RBNode* +rb_find_node_by(RBTree * __restrict tree, + void * __restrict key, + const DsCmpFn cmp) { + RBNode *iter, *nullNode; + + iter = tree->root->chld[RB_RIGHT]; + nullNode = tree->nullNode; + + while (iter != nullNode) { int cmpRet; - cmpRet = tree->cmp(iter->key, key); + cmpRet = cmp(iter->key, key); if (cmpRet == 0) break; @@ -568,7 +590,7 @@ rb_find_node(RBTree *tree, void *key) { iter = iter->chld[cmpRet < 0]; } - if (!iter || iter == tree->nullNode) + if (!iter || iter == nullNode) return NULL; return iter;