From: Ben Pfaff Date: Mon, 4 Jun 2007 01:36:06 +0000 (+0000) Subject: Add ability for reverse iteration to tower code, and corresponding X-Git-Tag: v0.6.0~454 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04bf0e1fed86a5dc9032f2fc8d89ed6217b566e1;p=pspp-builds.git Add ability for reverse iteration to tower code, and corresponding tests. --- diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog index 29acbae1..9e965630 100644 --- a/src/libpspp/ChangeLog +++ b/src/libpspp/ChangeLog @@ -1,3 +1,15 @@ +2007-06-03 Ben Pfaff + + 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 * tower.c: Cache repeated lookups of a single tower element. This diff --git a/src/libpspp/tower.c b/src/libpspp/tower.c index 79801b3a..0786bbbc 100644 --- a/src/libpspp/tower.c +++ b/src/libpspp/tower.c @@ -27,8 +27,11 @@ 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); +} /* 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 diff --git a/src/libpspp/tower.h b/src/libpspp/tower.h index 5a4c08e2..674564c6 100644 --- a/src/libpspp/tower.h +++ b/src/libpspp/tower.h @@ -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 */ diff --git a/tests/ChangeLog b/tests/ChangeLog index 5c89d0da..cf8a76bc 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,7 @@ 2007-06-03 Ben Pfaff + * 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 diff --git a/tests/libpspp/tower-test.c b/tests/libpspp/tower-test.c index f78fb892..a59760c8 100644 --- a/tests/libpspp/tower-test.c +++ b/tests/libpspp/tower-test.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -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); } /* Tests inserting all possible sets of block heights into a