1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-25 18:53:08 +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 # -O, so that we get data flow analysis, which helps to find more bugs
#LDFLAGS=-pg #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 OBJS_rbtest = rbtest.o jrb.o
all: qpkg rbtest all: qpkg rbtest

View File

@ -8,6 +8,10 @@
So the tree is clearly degenerated. 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 - check whether introducing a new package would cause a conflict

View File

@ -4,9 +4,6 @@
#include "id.h" #include "id.h"
#define NODE2ID(n) ((struct id *) n)
static struct id *free_id = NULL; 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 = alloc_type(struct tree);
tree->comp = comp; tree->comp = comp;
tree->root = NULL; tree->root = make_jrb();
return tree; 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 *make_id(struct tree *tree, const char *s, size_t len)
{ {
struct id *id; struct id *id;
struct node *node; struct jrb *node;
if (!free_id) if (!free_id)
free_id = alloc_type(struct 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->s = s;
id->len = len; id->len = len;
id->value = NULL; id->value = NULL;
node = add_node(tree, &id->node); node = jrb_find(tree->root, id, tree->comp);
if (node) if (node)
return NODE2ID(node); return node->key;
id->jrb = jrb_insert(tree->root, id, NULL, tree->comp);
free_id = NULL; free_id = NULL;
return id; return id;
} }
@ -82,48 +56,26 @@ const struct id *find_id(const struct tree *tree, const char *s, size_t len)
.s = s, .s = s,
.len = len .len = len
}; };
const struct node *n = tree->root; struct jrb *node;
int cmp;
while (n) { node = jrb_find(tree->root, &id, tree->comp);
cmp = tree->comp(&id, NODE2ID(n)); return node ? node->key : NULL;
if (cmp < 0)
n = n->left;
else if (cmp > 0)
n = n->right;
else
return NODE2ID(n);
}
return NULL;
} }
const struct id *first_id(const struct tree *tree) const struct id *first_id(const struct tree *tree)
{ {
const struct node *n = tree->root; struct jrb *node;
if (!n) node = jrb_first(tree->root);
return NULL; return node ? node->key : NULL;
while (n->left)
n = n->left;
return NODE2ID(n);
} }
const struct id *next_id(const struct id *id) const struct id *next_id(const struct id *id)
{ {
const struct node *n = &id->node; struct jrb *next;
if (n->right) { next = jrb_next(id->jrb);
n = n->right; return next ? next->key : NULL;
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;
} }

View File

@ -3,25 +3,18 @@
#include <sys/types.h> #include <sys/types.h>
#include "jrb.h"
struct id; 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 { struct tree {
int (*comp)(const struct id *a, const struct id *b); int (*comp)(const struct id *a, const struct id *b);
struct node *root; struct jrb *root;
}; };
struct id { struct id {
struct node node; struct jrb *jrb;
const char *s; const char *s;
size_t len; size_t len;
void *value; void *value;