]> git.mdlowis.com Git - projs/libcds.git/commitdiff
Merge from dev
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 3 Sep 2014 00:23:30 +0000 (20:23 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 3 Sep 2014 00:23:30 +0000 (20:23 -0400)
1  2 
Rakefile
source/cursor/cursor.h
source/list/list.c
source/rbt/rbt.c
source/rbt/rbt.h

diff --cc Rakefile
index cdecb6272463afa29557a51ab4617bde19837530,cce88991a2a1cb9cf1e1dd16bab5a7136754ef8e..5c88c39d7a1d1000abc4c5aeda49d462d4df8141
+++ b/Rakefile
@@@ -24,7 -24,8 +24,7 @@@ en
  TestEnv = Env.clone  do |env|
    env.build_dir('source','build/obj/test_source')
    env.build_dir('tests','build/obj/tests/source')
-   env['CFLAGS']  += ['-DLEAK_DETECT_LEVEL=1', '--coverage']
+   env['CFLAGS']  += ['-g', '--coverage', '-DLEAK_DETECT_LEVEL=1', '-DTESTING']
 -  #env['CFLAGS']  += ['-DNDEBUG'] #disables asserts so they won't effect coverage analysis
    env["LDFLAGS"] += ['--coverage']
    env['CPPPATH'] += Dir['tests/']
  end
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d23e79717dcd97f6bc2f8fa2a8f647eadec4268f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/**
++  @file cursor.h
++  @brief Generic cursor module for moving over data structures.
++  $Revision$
++  $HeadURL$
++  */
++#ifndef CURSOR_H
++#define CURSOR_H
++
++#include "mem.h"
++
++typedef enum {
++    FORWARD,
++    BACKWARD
++} advance_dir_t;
++
++typedef bool (*tester_t)(void* env, advance_dir_t dir);
++
++typedef void (*advancer_t)(void* env, advance_dir_t dir);
++
++typedef void* (*getter_t)(void* env);
++
++typedef void (*setter_t)(void* env, void* val);
++
++struct crsr_t;
++
++typedef struct crsr_t crsr_t;
++
++crsr_t* crsr_new(void* p_state, tester_t p_test, advancer_t p_advance, getter_t p_get, setter_t p_set);
++crsr_t* crsr_copy(crsr_t* p_crsr);
++void crsr_advance(crsr_t* p_crsr, int steps);
++void crsr_next(crsr_t* p_crsr);
++void crsr_prev(crsr_t* p_crsr);
++bool crsr_has_next(crsr_t* p_crsr);
++bool crsr_has_prev(crsr_t* p_crsr);
++void* crsr_get(crsr_t* p_crsr);
++void crsr_set(crsr_t* p_crsr, void* val);
++
++#endif /* CURSOR_H */
Simple merge
index 8e42fc93a3e7d0670138fbc39c03f60b644d7f76,4d426ac46479f61b53cc613fa44048a0eb4d5b75..b17f3ac59ab6150aecf544a5b77c4c74b4c75ca5
@@@ -19,8 -15,9 +19,9 @@@ static int rbt_default_comparator(void
  
  /* rbt_t */
  static void rbt_free(void* v_tree){
 -      rbt_t* tree = (rbt_t*) v_tree;
 -      assert(NULL != tree);
 -      if(tree->root) mem_release(tree->root);
 +    rbt_t* tree = (rbt_t*) v_tree;
-     if(tree && tree->root) mem_release(tree->root);
++    assert(NULL != tree);
++    if(tree->root) mem_release(tree->root);
  }
  
  rbt_t* rbt_new(comparator_t comparator){
  
  /* rbt_node_t */
  static void rbt_node_free(void* v_node){
 -      rbt_node_t* node = (rbt_node_t*) v_node;
 -      assert(NULL != node);
 -      mem_release(node->contents);
 -      if(node->left) mem_release(node->left);
 -      if(node->right) mem_release(node->right);
 +    rbt_node_t* node = (rbt_node_t*) v_node;
-     if(node){
-         mem_release(node->contents);
-         if(node->left) mem_release(node->left);
-         if(node->right) mem_release(node->right);
-     }
++    assert(NULL != node);
++    mem_release(node->contents);
++    if(node->left) mem_release(node->left);
++    if(node->right) mem_release(node->right);
  }
  
+ #ifndef TESTING
+ static
+ #endif
  rbt_node_t* rbt_node_new(void* contents){
 -      rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free);
 -      node->left = NULL;
 -      node->right = NULL;
 -      node->parent = NULL;
 -      node->contents = contents;
 -      node->color = RED;
 -      return node;
 +    rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free);
 +    node->left = NULL;
 +    node->right = NULL;
 +    node->parent = NULL;
 +    node->contents = contents;
 +    node->color = RED;
 +    return node;
  }
  
  
  /* ---------------------------------------- */
  /*    informational / querying functions    */
  /* ---------------------------------------- */
+ #ifndef TESTING
+ static
+ #endif
  rbt_color_t rbt_node_color(rbt_node_t* node){
 -      //leaves are NULL and black implicitly
 -      return (node ? node->color : BLACK);
 +    //leaves are NULL and black implicitly
 +    return (node ? node->color : BLACK);
  }
  
  static rbt_node_t* rbt_lookup_node(rbt_t* tree, rbt_node_t* node, void* value){
@@@ -80,12 -81,14 +85,13 @@@ static rbt_node_t* rightmost_descendant
  }
  
  static int rbt_count(rbt_node_t* node){
 -      return (!node ? 0 : (1 + rbt_count(node->left) + rbt_count(node->right)));
 +    return (!node ? 0 : (1 + rbt_count(node->left) + rbt_count(node->right)));
  }
- int rbt_count_nodes(rbt_t* tree){
+ int rbt_size(rbt_t* tree){
 -      return rbt_count(tree->root);
 +    return rbt_count(tree->root);
  }
  
 -
  /* ----------------------------------------- */
  /*    generally helpful tree manipulation    */
  /* ----------------------------------------- */
@@@ -102,16 -105,15 +108,15 @@@ typedef enum 
  } direction_t;
  
  static void rbt_rotate(rbt_t* tree, rbt_node_t* node, direction_t direction){
 -      rbt_node_t* edon = (direction == LEFT) ? node->right : node->left;
 -      assert(NULL != edon);
 -      rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right));
 -      rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left));
 -      rbt_node_replace(tree, node, edon);
 -      *node_side = *edon_side; //safe to overwrite; points to edon
 -      if(*edon_side) (*edon_side)->parent = node;
 -      *edon_side = node;
 -      node->parent = edon;
 +    rbt_node_t* edon = (direction == LEFT) ? node->right : node->left;
-     if(edon){
-         rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right));
-         rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left));
-         rbt_node_replace(tree, node, edon);
-         *node_side = *edon_side; //safe to overwrite; points to edon
-         if(*edon_side) (*edon_side)->parent = node;
-         *edon_side = node;
-         node->parent = edon;
-     } /* else rotation isn't allowed */
++    assert(NULL != edon);
++    rbt_node_t** edon_side = (direction == LEFT ? &(edon->left) : &(edon->right));
++    rbt_node_t** node_side = (direction == LEFT ? &(node->right) : &(node->left));
++    rbt_node_replace(tree, node, edon);
++    *node_side = *edon_side; //safe to overwrite; points to edon
++    if(*edon_side) (*edon_side)->parent = node;
++    *edon_side = node;
++    node->parent = edon;
  }
  
  
  /* -------------------- */
  
  static void rbt_ins_rebalance(rbt_t* tree, rbt_node_t* node, direction_t heavy_side){
 -      rbt_node_t* parent = node->parent;
 -      assert(NULL != parent);
 -      rbt_node_t* grandparent = parent->parent;
 -      rbt_rotate(tree, grandparent, (heavy_side == LEFT ? RIGHT : LEFT));
 -      parent->color = BLACK;
 -      grandparent->color = RED;
 +    rbt_node_t* parent = node->parent;
-     rbt_node_t* grandparent = (parent ? parent->parent : NULL);
++    assert(NULL != parent);
++    rbt_node_t* grandparent = parent->parent;
 +    rbt_rotate(tree, grandparent, (heavy_side == LEFT ? RIGHT : LEFT));
 +    parent->color = BLACK;
 +    grandparent->color = RED;
  }
  
  static void rbt_ins_recolor(rbt_t* tree, rbt_node_t* node){
@@@ -169,51 -172,50 +175,49 @@@ static void rbt_insert_node(rbt_t* tree
  }
  
  rbt_node_t* rbt_insert(rbt_t* tree, void* value){
 -      rbt_node_t* new_node = rbt_node_new(value);
 -      rbt_insert_node(tree, new_node, tree->root);
 -      return new_node;
 +    rbt_node_t* new_node = rbt_node_new(value);
 +    rbt_insert_node(tree, new_node, tree->root);
 +    return new_node;
  }
  
--
  /* ------------------- */
  /*    removal  code    */
  /* ------------------- */
  
  //node has a count -1 of black nodes to leaves relative to the rest of the tree
  static void rbt_del_rebalance(rbt_t* tree, rbt_node_t* node){
 -      rbt_node_t* parent = node->parent;
 -      if(parent){
 -              direction_t node_side = (node == parent->left ? LEFT : RIGHT);
 -              rbt_node_t* sib = (node_side == LEFT ? parent->right : parent->left);
 -              assert(NULL != sib);
 -              //nibling: gender neutral term for niece or nephew.
 -              rbt_node_t* inside_nibling = node_side == LEFT ? sib->left : sib->right;
 -              rbt_node_t* outside_nibling = node_side == LEFT ? sib->right : sib->left;
 -              if(RED == rbt_node_color(sib)){
 -                      //rotate so sib is black & recurse w/ new scenario
 -                      rbt_rotate(tree, parent, node_side);
 -                      parent->color = RED;
 -                      sib->color = BLACK;
 -                      rbt_del_rebalance(tree, node);
 -              }else if(BLACK == rbt_node_color(inside_nibling) && BLACK == rbt_node_color(outside_nibling)){
 -                      //both niblings are black ; can paint sib red & rebalance on parent
 -                      sib->color = RED;
 -                      if(RED == rbt_node_color(parent)) parent->color = BLACK;
 -                      else rbt_del_rebalance(tree, parent);
 -              }else if(BLACK == rbt_node_color(outside_nibling)){
 -                      //convert "inside" case to "outside" case & recurse w/ new scenario
 -                      rbt_rotate(tree, sib, (node_side == LEFT ? RIGHT : LEFT));
 -                      sib->color = RED;
 -                      inside_nibling->color = BLACK;
 -                      rbt_del_rebalance(tree, node);
 -              }else{
 -                      rbt_rotate(tree, parent, node_side);
 -                      sib->color = parent->color;
 -                      parent->color = BLACK;
 -                      outside_nibling->color = BLACK;
 -              }
 -      }
 +    rbt_node_t* parent = node->parent;
 +    if(parent){
 +        direction_t node_side = (node == parent->left ? LEFT : RIGHT);
 +        rbt_node_t* sib = (node_side == LEFT ? parent->right : parent->left);
++        assert(NULL != sib);
 +        //nibling: gender neutral term for niece or nephew.
-         rbt_node_t* inside_nibling = sib ? (node_side == LEFT ? sib->left : sib->right) : NULL;
-         rbt_node_t* outside_nibling = sib ? (node_side == LEFT ? sib->right : sib->left) : NULL;
++        rbt_node_t* inside_nibling = node_side == LEFT ? sib->left : sib->right;
++        rbt_node_t* outside_nibling = node_side == LEFT ? sib->right : sib->left;
 +        if(RED == rbt_node_color(sib)){
 +            //rotate so sib is black & recurse w/ new scenario
 +            rbt_rotate(tree, parent, node_side);
 +            parent->color = RED;
 +            sib->color = BLACK;
 +            rbt_del_rebalance(tree, node);
 +        }else if(BLACK == rbt_node_color(inside_nibling) && BLACK == rbt_node_color(outside_nibling)){
 +            //both niblings are black ; can paint sib red & rebalance on parent
 +            sib->color = RED;
 +            if(RED == rbt_node_color(parent)) parent->color = BLACK;
 +            else rbt_del_rebalance(tree, parent);
 +        }else if(BLACK == rbt_node_color(outside_nibling)){
 +            //convert "inside" case to "outside" case & recurse w/ new scenario
 +            rbt_rotate(tree, sib, (node_side == LEFT ? RIGHT : LEFT));
 +            sib->color = RED;
 +            inside_nibling->color = BLACK;
 +            rbt_del_rebalance(tree, node);
 +        }else{
 +            rbt_rotate(tree, parent, node_side);
 +            sib->color = parent->color;
 +            parent->color = BLACK;
 +            outside_nibling->color = BLACK;
 +        }
-     }else{
-         node->color = BLACK; //TODO: verify this is necessary
 +    }
  }
  
  static void rbt_delete_node(rbt_t* tree, rbt_node_t* node){
Simple merge