1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-22 08:24:41 +02:00

qpkg: converted dumb binary trees to red-black trees (in progress)

This is a change of the underlying mechanism but it's not polished or
optimized yet. The compare functions haven't been updated, so they work
but produce compiler warnings because of type mismatches.

- Makefile (OBJS): added jrb.o
- id.h, id.c: use jrb instead of own dumb binary trees
- TODO: brag about the efficiency improvement
This commit is contained in:
Werner Almesberger 2010-11-19 21:17:08 -03:00
parent a8ed4dcb23
commit e1814ce372
4 changed files with 23 additions and 74 deletions

View File

@ -2,7 +2,7 @@ CFLAGS = -Wall -Wshadow -Wmissing-prototypes -g -O
# -O, so that we get data flow analysis, which helps to find more bugs
#LDFLAGS=-pg
OBJS = gobble.o id.o prereq.o qpkg.o
OBJS = gobble.o id.o prereq.o qpkg.o jrb.o
OBJS_rbtest = rbtest.o jrb.o
all: qpkg rbtest

View File

@ -8,6 +8,10 @@
So the tree is clearly degenerated.
Update: after switching to red-black trees, we get only 1497604 calls
to comp_id. This is 130% of the "good case" estimate above. Insertion
of a new node is currently done with two lookup, so we'll get rid of
some more lookups after further optimization.
- check whether introducing a new package would cause a conflict

View File

@ -4,9 +4,6 @@
#include "id.h"
#define NODE2ID(n) ((struct id *) n)
static struct id *free_id = NULL;
@ -28,39 +25,15 @@ struct tree *make_tree(int (*comp)(const struct id *a, const struct id *b))
tree = alloc_type(struct tree);
tree->comp = comp;
tree->root = NULL;
tree->root = make_jrb();
return tree;
}
static struct node *add_node(struct tree *tree, struct node *node)
{
struct node **p, *last;
int cmp;
p = &tree->root;
last = NULL;
while (*p) {
last = *p;
cmp = tree->comp(NODE2ID(node), NODE2ID(*p));
if (cmp < 0)
p = &(*p)->left;
else if (cmp > 0)
p = &(*p)->right;
else
return *p;
}
*p = node;
node->up = last;
node->left = node->right = NULL;
return NULL;
}
struct id *make_id(struct tree *tree, const char *s, size_t len)
{
struct id *id;
struct node *node;
struct jrb *node;
if (!free_id)
free_id = alloc_type(struct id);
@ -68,9 +41,10 @@ struct id *make_id(struct tree *tree, const char *s, size_t len)
id->s = s;
id->len = len;
id->value = NULL;
node = add_node(tree, &id->node);
node = jrb_find(tree->root, id, tree->comp);
if (node)
return NODE2ID(node);
return node->key;
id->jrb = jrb_insert(tree->root, id, NULL, tree->comp);
free_id = NULL;
return id;
}
@ -82,48 +56,26 @@ const struct id *find_id(const struct tree *tree, const char *s, size_t len)
.s = s,
.len = len
};
const struct node *n = tree->root;
int cmp;
struct jrb *node;
while (n) {
cmp = tree->comp(&id, NODE2ID(n));
if (cmp < 0)
n = n->left;
else if (cmp > 0)
n = n->right;
else
return NODE2ID(n);
}
return NULL;
node = jrb_find(tree->root, &id, tree->comp);
return node ? node->key : NULL;
}
const struct id *first_id(const struct tree *tree)
{
const struct node *n = tree->root;
struct jrb *node;
if (!n)
return NULL;
while (n->left)
n = n->left;
return NODE2ID(n);
node = jrb_first(tree->root);
return node ? node->key : NULL;
}
const struct id *next_id(const struct id *id)
{
const struct node *n = &id->node;
struct jrb *next;
if (n->right) {
n = n->right;
while (n->left)
n = n->left;
return NODE2ID(n);
}
while (n->up) {
if (n == n->up->left)
return NODE2ID(n->up);
n = n->up;
}
return NULL;
next = jrb_next(id->jrb);
return next ? next->key : NULL;
}

View File

@ -3,25 +3,18 @@
#include <sys/types.h>
#include "jrb.h"
struct id;
/*
* @@@ basic binary trees are not a good choice. should use rb.
* To ease future migration, we separate the node structure from the rest.
*/
struct node {
struct node *up, *left, *right;
};
struct tree {
int (*comp)(const struct id *a, const struct id *b);
struct node *root;
struct jrb *root;
};
struct id {
struct node node;
struct jrb *jrb;
const char *s;
size_t len;
void *value;