turns such lookups into O(1) operations without harming the big-O
of other operations.
* tower.h (struct tower): Add members for caching.
2007-06-03 Ben Pfaff <blp@gnu.org>
2007-06-03 Ben Pfaff <blp@gnu.org>
+ * tower.c: Cache repeated lookups of a single tower element. This
+ turns such lookups into O(1) operations without harming the big-O
+ of other operations.
+
+ * tower.h (struct tower): Add members for caching.
+
* range-set.c (range_set_clone): New function.
* array.c (insert_range): New function.
* range-set.c (range_set_clone): New function.
* array.c (insert_range): New function.
#include <libpspp/tower.h>
#include <libpspp/tower.h>
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
tower_init (struct tower *t)
{
abt_init (&t->abt, NULL, reaugment_tower_node, NULL);
tower_init (struct tower *t)
{
abt_init (&t->abt, NULL, reaugment_tower_node, NULL);
+ t->cache_bottom = ULONG_MAX;
}
/* Returns true if T contains no nodes, false otherwise. */
}
/* Returns true if T contains no nodes, false otherwise. */
new->height = height;
abt_insert_before (&t->abt, under ? &under->abt_node : NULL,
&new->abt_node);
new->height = height;
abt_insert_before (&t->abt, under ? &under->abt_node : NULL,
&new->abt_node);
+ t->cache_bottom = ULONG_MAX;
}
/* Deletes NODE from tower T. */
}
/* Deletes NODE from tower T. */
{
struct tower_node *next = next_node (t, node);
abt_delete (&t->abt, &node->abt_node);
{
struct tower_node *next = next_node (t, node);
abt_delete (&t->abt, &node->abt_node);
+ t->cache_bottom = ULONG_MAX;
assert (new_height > 0);
node->height = new_height;
abt_reaugmented (&t->abt, &node->abt_node);
assert (new_height > 0);
node->height = new_height;
abt_reaugmented (&t->abt, &node->abt_node);
+ t->cache_bottom = ULONG_MAX;
}
/* Removes nodes FIRST through LAST (exclusive) from tower SRC
}
/* Removes nodes FIRST through LAST (exclusive) from tower SRC
abt_insert_before (&dst->abt, under ? &under->abt_node : NULL,
&first->abt_node);
}
abt_insert_before (&dst->abt, under ? &under->abt_node : NULL,
&first->abt_node);
}
+ dst->cache_bottom = src->cache_bottom = ULONG_MAX;
}
/* Returns the node at the given HEIGHT from the bottom of tower
}
/* Returns the node at the given HEIGHT from the bottom of tower
of the returned node, which may be less than HEIGHT if HEIGHT
refers to the middle of a node instead of its bottom. */
struct tower_node *
of the returned node, which may be less than HEIGHT if HEIGHT
refers to the middle of a node instead of its bottom. */
struct tower_node *
-tower_lookup (const struct tower *t,
+tower_lookup (const struct tower *t_,
unsigned long height,
unsigned long *node_start)
{
unsigned long height,
unsigned long *node_start)
{
+ struct tower *t = (struct tower *) t_;
struct abt_node *p;
assert (height < tower_height (t));
struct abt_node *p;
assert (height < tower_height (t));
+ if (height >= t->cache_bottom && height - t->cache_bottom < t->cache->height)
+ {
+ *node_start = t->cache_bottom;
+ return t->cache;
+ }
+
*node_start = 0;
p = t->abt.root;
for (;;)
*node_start = 0;
p = t->abt.root;
for (;;)
if (height < node_height)
{
/* Our goal height is in P. */
if (height < node_height)
{
/* Our goal height is in P. */
+ t->cache = node;
+ t->cache_bottom = *node_start;
/* A tower. */
struct tower
{
/* A tower. */
struct tower
{
- struct abt abt; /* Tree. */
+ struct abt abt; /* Tree. */
+ struct tower_node *cache; /* Cache node. */
+ unsigned long int cache_bottom; /* Height of cache's bottom. */
};
void tower_init (struct tower *);
};
void tower_init (struct tower *);