Add ability for reverse iteration to tower code, and corresponding
authorBen Pfaff <blp@gnu.org>
Mon, 4 Jun 2007 01:36:06 +0000 (01:36 +0000)
committerBen Pfaff <blp@gnu.org>
Mon, 4 Jun 2007 01:36:06 +0000 (01:36 +0000)
tests.

src/libpspp/ChangeLog
src/libpspp/tower.c
src/libpspp/tower.h
tests/ChangeLog
tests/libpspp/tower-test.c

index 29acbae1f3b6ca9e0ce51df18e7a3b75dac1a6f4..9e965630829ae180a53e91db9e02aff9b3f6d2a5 100644 (file)
@@ -1,3 +1,15 @@
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       Add ability for reverse iteration to tower code.
+       
+       * tower.c (tower_last): New function.
+       (tower_prev): New function.
+       (abt_to_tower_node): New function.
+       (first_node): Use abt_to_tower_node.
+       (last_node): New function.
+       (next_ndoe): Use abt_to_tower_node.
+       (prev_node): New function.
+
 2007-06-03  Ben Pfaff  <blp@gnu.org>
 
        * tower.c: Cache repeated lookups of a single tower element.  This
index 79801b3a07d774de0f4945c28c531bc54ac62c5a..0786bbbc2fd59212f847e5bc321c87bc5575d4c2 100644 (file)
 
 static struct tower_node *abt_to_tower_node (const struct abt_node *);
 static struct tower_node *first_node (const struct tower *);
+static struct tower_node *last_node (const struct tower *);
 static struct tower_node *next_node (const struct tower *,
                                      const struct tower_node *);
+static struct tower_node *prev_node (const struct tower *,
+                                     const struct tower_node *);
 static unsigned long int get_subtree_height (const struct abt_node *);
 static void reaugment_tower_node (struct abt_node *,
                                   const struct abt_node *,
@@ -184,6 +187,14 @@ tower_first (const struct tower *t)
   return first_node (t);
 }
 
+/* Returns the node at the top of tower T, or a null pointer if T
+   is empty. */
+struct tower_node *
+tower_last (const struct tower *t) 
+{
+  return last_node (t);
+}
+
 /* If NODE is nonnull, returns the node just above NODE in tower
    T, or a null pointer if NODE is the topmost node in T.
    If NODE is null, acts like tower_first. */
@@ -192,6 +203,15 @@ tower_next (const struct tower *t, const struct tower_node *node)
 {
   return node != NULL ? next_node (t, node) : first_node (t);
 }
+
+/* If NODE is nonnull, returns the node just below NODE in tower
+   T, or a null pointer if NODE is the bottommost node in T.
+   If NODE is null, acts like tower_last. */
+struct tower_node *
+tower_prev (const struct tower *t, const struct tower_node *node) 
+{
+  return node != NULL ? prev_node (t, node) : last_node (t);
+}
 \f
 /* Returns the tower node corresponding to the given ABT_NODE. */
 static struct tower_node *
@@ -200,20 +220,39 @@ abt_to_tower_node (const struct abt_node *abt_node)
   return abt_data (abt_node, struct tower_node, abt_node);
 }
 
+/* Returns the tower node corresponding to the given ABT_NODE. */
+static struct tower_node *
+abt_to_tower_node_null (const struct abt_node *abt_node) 
+{
+  return abt_node != NULL ? abt_to_tower_node (abt_node) : NULL;
+}
+
 /* Returns the first node in TOWER. */
 static struct tower_node *
 first_node (const struct tower *t) 
 {
-  struct abt_node *abt_node = abt_first (&t->abt);
-  return abt_node != NULL ? abt_to_tower_node (abt_node) : NULL;
+  return abt_to_tower_node_null (abt_first (&t->abt));
+}
+
+/* Returns the first node in TOWER. */
+static struct tower_node *
+last_node (const struct tower *t) 
+{
+  return abt_to_tower_node_null (abt_last (&t->abt));
 }
 
 /* Returns the next node in TOWER after NODE. */
 static struct tower_node *
 next_node (const struct tower *t, const struct tower_node *node) 
 {
-  struct abt_node *abt_node = abt_next (&t->abt, &node->abt_node);
-  return abt_node != NULL ? abt_to_tower_node (abt_node) : NULL;
+  return abt_to_tower_node_null (abt_next (&t->abt, &node->abt_node));
+}
+
+/* Returns the previous node in TOWER before NODE. */
+static struct tower_node *
+prev_node (const struct tower *t, const struct tower_node *node) 
+{
+  return abt_to_tower_node_null (abt_prev (&t->abt, &node->abt_node));
 }
 
 /* Returns the total height of the nodes in the subtree rooted at
index 5a4c08e204f714aa334c054a73db8867518594f3..674564c685464ccbf6f8934e22a8ebf876add739 100644 (file)
@@ -97,7 +97,10 @@ struct tower_node *tower_lookup (const struct tower *,
                                  unsigned long int level,
                                  unsigned long int *node_start);
 struct tower_node *tower_first (const struct tower *);
+struct tower_node *tower_last (const struct tower *);
 struct tower_node *tower_next (const struct tower *,
                                const struct tower_node *);
+struct tower_node *tower_prev (const struct tower *,
+                               const struct tower_node *);
 
 #endif /* libpspp/tower.h */
index 5c89d0da36055f539ab32c91fa71da4e35e55f6d..cf8a76bc38f76d10f370fd784fbdf29d2f1d3a49 100644 (file)
@@ -1,5 +1,7 @@
 2007-06-03  Ben Pfaff  <blp@gnu.org>
 
+       * tests/tower-test.c: Also test tower_last, tower_prev functions.
+
        * tests/range-set-test.c: Also test the range_set_clone function.
 
 2007-05-06  Ben Pfaff  <blp@gnu.org>
index f78fb8920700b50d2e77cca2dd86e0d4b69adaa3..a59760c80a89bfd13c0e5e273f5282d6e54428e6 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <assert.h>
 #include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -289,6 +290,15 @@ check_tower (struct tower *t,
       check (tower_node_to_block (node)->x == blocks[i].x);
     }
   check (i == block_cnt);
+
+  for (node = tower_last (t), i = block_cnt - 1;
+       node != NULL;
+       node = tower_prev (t, node), i--) 
+    {
+      check (tower_node_get_height (node) == blocks[i].height);
+      check (tower_node_to_block (node)->x == blocks[i].x);
+    }
+  check (i == SIZE_MAX);
 }
 \f
 /* Tests inserting all possible sets of block heights into a