pike.git / src / rbtree_low.h

version» Context lines:

pike.git/src/rbtree_low.h:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: rbtree_low.h,v 1.5 2002/10/11 01:39:37 nilsson Exp $ + || $Id: rbtree_low.h,v 1.6 2002/12/19 01:44:00 mast Exp $   */      /* The lower level api for using rbtree. This is in a separate file    * since it's quite macro heavy.    *    * Created 2001-04-27 by Martin Stjernholm    */      #ifndef RBTREE_LOW_H   #define RBTREE_LOW_H
pike.git/src/rbtree_low.h:54:    struct rb_node_hdr *oldbase,    struct rb_node_hdr *newbase);      #define RBSTACK_INIT(rbstack) \    struct rbstack_slice PIKE_CONCAT3 (_, rbstack, _top_) = { \    DO_IF_RB_STATS (0 COMMA 0 COMMA) \    NULL, \    {NULL,} \    }; \    struct rbstack_ptr rbstack = { \ -  (PIKE_CONCAT3 (_, rbstack, _top_).up = NULL, \ -  &PIKE_CONCAT3 (_, rbstack, _top_)), \ +  &PIKE_CONCAT3 (_, rbstack, _top_), \    0 \    }      #define RBSTACK_PUSH(rbstack, node) do { \    if ((rbstack).ssp < STACK_SLICE_SIZE) { \    (rbstack).slice->stack[(rbstack).ssp++] = (node); \    } \    else rbstack_push (&(rbstack), node); \    DO_IF_RB_STATS ( \    if (++(rbstack).slice->depth > (rbstack).slice->maxdepth) \
pike.git/src/rbtree_low.h:184:    * between Run after the prev subtree has been recursed and before    * the next subtree is examined. Preceded by a between_*    * label.    * n_leaf Run when the next pointer of the node isn't a subtree.    * n_sub Run when the next pointer of the node is a subtree.    * pop Run when leaving the node. Preceded by a leave_* label.    */   #define LOW_RB_TRAVERSE(label, rbstack, node, push, p_leaf, p_sub, \    between, n_leaf, n_sub, pop) \    do { \ -  struct rb_node_hdr *rb_last_; \ +     DO_IF_RB_STATS (rb_num_traverses++); \    if (node) { \    PIKE_CONCAT (enter_, label): \    DO_IF_RB_STATS (rb_num_traverse_ops++); \    {push;} \    if ((node)->flags & RB_THREAD_PREV) \    {p_leaf;} \    else { \    {p_sub;} \    RBSTACK_PUSH (rbstack, node); \
pike.git/src/rbtree_low.h:212:    else { \    {n_sub;} \    RBSTACK_PUSH (rbstack, node); \    (node) = (node)->next; \    goto PIKE_CONCAT (enter_, label); \    } \    while (1) { \    PIKE_CONCAT (leave_, label): \    DO_IF_RB_STATS (rb_num_traverse_ops++); \    {pop;} \ -  rb_last_ = (node); \ +  { \ +  struct rb_node_hdr *rb_last_ = (node); \    RBSTACK_POP (rbstack, node); \    if (!(node)) break; \ -  if (rb_last_ == (node)->prev) \ +  /* Compare with next and not prev to avoid an infinite */ \ +  /* loop if a node (incorrectly) got prev == next. */ \ +  if (rb_last_ != (node)->next) \    goto PIKE_CONCAT (between_, label); \ -  +  } \    } \    } \    } while (0)      #define LOW_RB_DEBUG_TRAVERSE(label, rbstack, node, push, p_leaf, p_sub, \    between, n_leaf, n_sub, pop) \    do { \    size_t PIKE_CONCAT (depth_, label) = 0; \    LOW_RB_TRAVERSE( \    label, rbstack, node, \
pike.git/src/rbtree_low.h:253:   /* The `cmp' code should set the variable cmp_res to the result of the    * comparison between the key and the current node `node'. */   #define LOW_RB_FIND(node, cmp, got_lt, got_eq, got_gt) \    do { \    int cmp_res, found_eq_ = 0; \    DO_IF_RB_STATS ( \    size_t stat_depth_count_ = 0; \    rb_num_finds++; \    ); \    while (1) { \ -  DO_IF_DEBUG (if (!node) Pike_fatal ("Recursing into null node.\n")); \ +  DO_IF_DEBUG (if (!node) Pike_fatal ("Recursing into null node.\n")); \    DO_IF_RB_STATS ( \    if (++stat_depth_count_ > rb_max_depth) \    rb_max_depth = stat_depth_count_; \    rb_find_depth++; \    ); \    {cmp;} \    if (cmp_res < 0) \    if ((node)->flags & RB_THREAD_PREV) \    if (found_eq_) \    (node) = (node)->prev; \
pike.git/src/rbtree_low.h:299:      /* Variant of LOW_RB_FIND that assumes that `cmp' never returns 0. */   #define LOW_RB_FIND_NEQ(node, cmp, got_lt, got_gt) \    do { \    int cmp_res; \    DO_IF_RB_STATS ( \    size_t stat_depth_count_ = 0; \    rb_num_finds++; \    ); \    while (1) { \ -  DO_IF_DEBUG (if (!node) Pike_fatal ("Recursing into null node.\n")); \ +  DO_IF_DEBUG (if (!node) Pike_fatal ("Recursing into null node.\n")); \    DO_IF_RB_STATS ( \    if (++stat_depth_count_ > rb_max_depth) \    rb_max_depth = stat_depth_count_; \    rb_find_depth++; \    ); \    {cmp;} \    if (cmp_res < 0) { \    if ((node)->flags & RB_THREAD_PREV) { \    {got_gt;} \    break; \
pike.git/src/rbtree_low.h:329:    (node) = (node)->next; \    } \    } \    } while (0)      /* Tracks the way down a tree to a specific node and updates the stack    * as necessary for low_rb_link_* and low_rb_unlink_*. */   #define LOW_RB_TRACK(rbstack, node, cmp, got_lt, got_eq, got_gt) \    do { \    DO_IF_DEBUG ( \ -  if (RBSTACK_PEEK (rbstack)) Pike_fatal ("The stack is not empty.\n"); \ +  if (RBSTACK_PEEK (rbstack)) Pike_fatal ("The stack is not empty.\n"); \    ); \    DO_IF_RB_STATS (rb_num_finds--); \    LOW_RB_FIND ( \    node, \    { \    DO_IF_RB_STATS (rb_find_depth--); \    RBSTACK_PUSH (rbstack, node); \    {cmp;} \    }, \    got_lt, \    { \    while ((node) != RBSTACK_PEEK (rbstack)) \    RBSTACK_POP_IGNORE (rbstack); \    {got_eq;} \    }, got_gt); \    } while (0)      #define LOW_RB_TRACK_NEQ(rbstack, node, cmp, got_lt, got_gt) \    do { \    DO_IF_DEBUG ( \ -  if (RBSTACK_PEEK (rbstack)) Pike_fatal ("The stack is not empty.\n"); \ +  if (RBSTACK_PEEK (rbstack)) Pike_fatal ("The stack is not empty.\n"); \    ); \    DO_IF_RB_STATS (rb_num_finds--); \    LOW_RB_FIND_NEQ ( \    node, \    { \    DO_IF_RB_STATS (rb_find_depth--); \    RBSTACK_PUSH (rbstack, node); \    {cmp;} \    }, \    got_lt, got_gt); \    } while (0)      /* Goes to the first node in a tree while keeping the stack updated. */   #define LOW_RB_TRACK_FIRST(rbstack, node) \    do { \    DO_IF_DEBUG ( \ -  if (RBSTACK_PEEK (rbstack)) Pike_fatal ("The stack is not empty.\n"); \ +  if (RBSTACK_PEEK (rbstack)) Pike_fatal ("The stack is not empty.\n"); \    ); \    DO_IF_RB_STATS (rb_num_sidetracks++); \    if (node) { \    struct rb_node_hdr *rb_prev_ = node->prev; \    RBSTACK_PUSH (rbstack, node); \    DO_IF_RB_STATS (rb_num_sidetrack_ops++); \    while (rb_prev_) { \    RBSTACK_PUSH (rbstack, node = rb_prev_); \    DO_IF_RB_STATS (rb_num_sidetrack_ops++); \    rb_prev_ = node->prev; \    } \    } \    } while (0)      /* Goes to the next node in order while keeping the stack updated. */   #define LOW_RB_TRACK_NEXT(rbstack, node) \    do { \    DO_IF_DEBUG ( \    if (node != RBSTACK_PEEK (rbstack)) \ -  Pike_fatal ("Given node is not on top of stack.\n"); \ +  Pike_fatal ("Given node is not on top of stack.\n"); \    ); \    DO_IF_RB_STATS (rb_num_sidetracks++); \    if (node->flags & RB_THREAD_NEXT) { \    struct rb_node_hdr *rb_next_ = node->next; \    while ((node = RBSTACK_PEEK (rbstack)) != rb_next_) { \    RBSTACK_POP_IGNORE (rbstack); \    DO_IF_RB_STATS (rb_num_sidetrack_ops++); \    } \    } \    else { \
pike.git/src/rbtree_low.h:413:    node = node->prev; \    } \    } \    } while (0)      /* Goes to the previous node in order while keeping the stack updated. */   #define LOW_RB_TRACK_PREV(rbstack, node) \    do { \    DO_IF_DEBUG ( \    if (node != RBSTACK_PEEK (rbstack)) \ -  Pike_fatal ("Given node is not on top of stack.\n"); \ +  Pike_fatal ("Given node is not on top of stack.\n"); \    ); \    DO_IF_RB_STATS (rb_num_sidetracks++); \    if (node->flags & RB_THREAD_PREV) { \    struct rb_node_hdr *rb_prev_ = node->prev; \    while ((node = RBSTACK_PEEK (rbstack)) != rb_prev_) { \    RBSTACK_POP_IGNORE (rbstack); \    DO_IF_RB_STATS (rb_num_sidetrack_ops++); \    } \    } \    else { \