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:
parent
a8ed4dcb23
commit
e1814ce372
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
76
qpkg/id.c
76
qpkg/id.c
@ -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;
|
||||
}
|
||||
|
15
qpkg/id.h
15
qpkg/id.h
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user