aboutsummaryrefslogtreecommitdiffstats
path: root/module/avl
diff options
context:
space:
mode:
authorJorgen Lundman <[email protected]>2020-06-04 01:49:32 +0900
committerGitHub <[email protected]>2020-06-03 09:49:32 -0700
commit081de9a86d14562a5817f388c2949c423dcd1ea0 (patch)
tree5e2414794b369f20ad90247b42542d9e8c834c13 /module/avl
parent3bf3b164ee18b2897f9f8812f053704a10a1481d (diff)
Restore avl_update() calls and related functions
The macOS kmem implementation uses avl_update() and related functions. These same function exist in the Solaris AVL code but were removed because they were unused. Restore them. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Jorgen Lundman <[email protected]> Closes #10390
Diffstat (limited to 'module/avl')
-rw-r--r--module/avl/avl.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/module/avl/avl.c b/module/avl/avl.c
index 6d8fca214..cfe153a4c 100644
--- a/module/avl/avl.c
+++ b/module/avl/avl.c
@@ -809,6 +809,64 @@ avl_remove(avl_tree_t *tree, void *data)
} while (parent != NULL);
}
+#define AVL_REINSERT(tree, obj) \
+ avl_remove((tree), (obj)); \
+ avl_add((tree), (obj))
+
+boolean_t
+avl_update_lt(avl_tree_t *t, void *obj)
+{
+ void *neighbor;
+
+ ASSERT(((neighbor = AVL_NEXT(t, obj)) == NULL) ||
+ (t->avl_compar(obj, neighbor) <= 0));
+
+ neighbor = AVL_PREV(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+boolean_t
+avl_update_gt(avl_tree_t *t, void *obj)
+{
+ void *neighbor;
+
+ ASSERT(((neighbor = AVL_PREV(t, obj)) == NULL) ||
+ (t->avl_compar(obj, neighbor) >= 0));
+
+ neighbor = AVL_NEXT(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+boolean_t
+avl_update(avl_tree_t *t, void *obj)
+{
+ void *neighbor;
+
+ neighbor = AVL_PREV(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ neighbor = AVL_NEXT(t, obj);
+ if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) {
+ AVL_REINSERT(t, obj);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
void
avl_swap(avl_tree_t *tree1, avl_tree_t *tree2)
{
@@ -1030,3 +1088,6 @@ EXPORT_SYMBOL(avl_remove);
EXPORT_SYMBOL(avl_numnodes);
EXPORT_SYMBOL(avl_destroy_nodes);
EXPORT_SYMBOL(avl_destroy);
+EXPORT_SYMBOL(avl_update_lt);
+EXPORT_SYMBOL(avl_update_gt);
+EXPORT_SYMBOL(avl_update);