]> git.kaiwu.me - njs.git/commitdiff
Using nxt_rbtree_destroy_next() iterator for nxt_mem_cache_pool
authorIgor Sysoev <igor@sysoev.ru>
Sun, 12 Mar 2017 19:40:13 +0000 (22:40 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Sun, 12 Mar 2017 19:40:13 +0000 (22:40 +0300)
destruction without rbtree rebalancing.

nxt/nxt_mem_cache_pool.c
nxt/nxt_rbtree.c
nxt/nxt_rbtree.h

index edf3d78e28d6ab9e0835f05d147b94735f9b1716..2a2d28447d92397bb76bb1180886cee31b6878d9 100644 (file)
@@ -257,19 +257,16 @@ nxt_mem_cache_pool_is_empty(nxt_mem_cache_pool_t *pool)
 void
 nxt_mem_cache_pool_destroy(nxt_mem_cache_pool_t *pool)
 {
-    void                  *p;
+    void                   *p;
     nxt_rbtree_node_t      *node, *next;
     nxt_mem_cache_block_t  *block;
 
-    for (node = nxt_rbtree_min(&pool->blocks);
-         nxt_rbtree_is_there_successor(&pool->blocks, node);
-         node = next)
-    {
-        next = nxt_rbtree_node_successor(&pool->blocks, node);
+    next = nxt_rbtree_root(&pool->blocks);
 
-        block = (nxt_mem_cache_block_t *) node;
+    while (next != nxt_rbtree_sentinel(&pool->blocks)) {
 
-        nxt_rbtree_delete(&pool->blocks, &block->node);
+        node = nxt_rbtree_destroy_next(&pool->blocks, &next);
+        block = (nxt_mem_cache_block_t *) node;
 
         p = block->start;
 
index 852317d4f772565107ff305e92dbdb9d0283110c..18e8acca08fac33bba4319ec0bffcbdfba7fe179 100644 (file)
@@ -495,3 +495,37 @@ nxt_rbtree_parent_relink(nxt_rbtree_node_t *subst, nxt_rbtree_node_t *node)
     link = (node == parent->left) ? &parent->left : &parent->right;
     *link = subst;
 }
+
+
+nxt_rbtree_node_t *
+nxt_rbtree_destroy_next(nxt_rbtree_t *tree, nxt_rbtree_node_t **next)
+{
+    nxt_rbtree_node_t  *node, *subst, *parent, *sentinel;
+
+    sentinel = nxt_rbtree_sentinel(tree);
+
+    /* Find the leftmost node. */
+    for (node = *next; node->left != sentinel; node = node->left);
+
+    /* Replace the leftmost node with its right child. */
+    subst = node->right;
+    parent = node->parent;
+
+    parent->left = subst;
+    subst->parent = parent;
+
+    /*
+     * The right child is used as the next start node.  If the right child
+     * is the sentinel then parent of the leftmost node is used as the next
+     * start node.  The parent of the root node is the sentinel so after
+     * the single root node will be replaced with the sentinel, the next
+     * start node will be equal to the sentinel and iteration will stop.
+     */
+    if (subst == sentinel) {
+        subst = parent;
+    }
+
+    *next = subst;
+
+    return node;
+}
index 00adc8bd69b9aefb776d62a604036324a62adc7d..9501ad079abf89fac49a454b054767f4bc9415f7 100644 (file)
@@ -111,5 +111,16 @@ NXT_EXPORT nxt_rbtree_node_t
     nxt_rbtree_part_t *node);
 NXT_EXPORT void nxt_rbtree_delete(nxt_rbtree_t *tree, nxt_rbtree_part_t *node);
 
+/*
+ * nxt_rbtree_destroy_next() is iterator to use only while rbtree destruction.
+ * It deletes a node from rbtree and returns the node.  The rbtree is not
+ * rebalanced after deletion.  At the beginning the "next" parameter should
+ * be equal to rbtree root.  The iterator should be called in loop until
+ * the "next" parameter will be equal to the rbtree sentinel.  No other
+ * operations must be performed on the rbtree while destruction.
+ */
+NXT_EXPORT nxt_rbtree_node_t *nxt_rbtree_destroy_next(nxt_rbtree_t *tree,
+    nxt_rbtree_node_t **next);
+
 
 #endif /* _NXT_RBTREE_H_INCLUDED_ */