[njs] Using nxt_rbtree_destroy_next() iterator for nxt_mem_cache_pool

Igor Sysoev igor at sysoev.ru
Mon Mar 13 13:38:29 UTC 2017


details:   http://hg.nginx.org/njs/rev/6bda82d5bd54
branches:  
changeset: 312:6bda82d5bd54
user:      Igor Sysoev <igor at sysoev.ru>
date:      Sun Mar 12 22:40:13 2017 +0300
description:
Using nxt_rbtree_destroy_next() iterator for nxt_mem_cache_pool
destruction without rbtree rebalancing.

diffstat:

 nxt/nxt_mem_cache_pool.c |  13 +++++--------
 nxt/nxt_rbtree.c         |  34 ++++++++++++++++++++++++++++++++++
 nxt/nxt_rbtree.h         |  11 +++++++++++
 3 files changed, 50 insertions(+), 8 deletions(-)

diffs (90 lines):

diff -r 214afa2466a0 -r 6bda82d5bd54 nxt/nxt_mem_cache_pool.c
--- a/nxt/nxt_mem_cache_pool.c	Wed Feb 01 11:33:05 2017 +0300
+++ b/nxt/nxt_mem_cache_pool.c	Sun Mar 12 22:40:13 2017 +0300
@@ -257,20 +257,17 @@ nxt_mem_cache_pool_is_empty(nxt_mem_cach
 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);
 
+    while (next != nxt_rbtree_sentinel(&pool->blocks)) {
+
+        node = nxt_rbtree_destroy_next(&pool->blocks, &next);
         block = (nxt_mem_cache_block_t *) node;
 
-        nxt_rbtree_delete(&pool->blocks, &block->node);
-
         p = block->start;
 
         if (block->type != NXT_MEM_CACHE_EMBEDDED_BLOCK) {
diff -r 214afa2466a0 -r 6bda82d5bd54 nxt/nxt_rbtree.c
--- a/nxt/nxt_rbtree.c	Wed Feb 01 11:33:05 2017 +0300
+++ b/nxt/nxt_rbtree.c	Sun Mar 12 22:40:13 2017 +0300
@@ -495,3 +495,37 @@ nxt_rbtree_parent_relink(nxt_rbtree_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;
+}
diff -r 214afa2466a0 -r 6bda82d5bd54 nxt/nxt_rbtree.h
--- a/nxt/nxt_rbtree.h	Wed Feb 01 11:33:05 2017 +0300
+++ b/nxt/nxt_rbtree.h	Sun Mar 12 22:40:13 2017 +0300
@@ -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_ */


More information about the nginx-devel mailing list