mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-25 19:59:23 +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
|
# -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
76
qpkg/id.c
76
qpkg/id.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
15
qpkg/id.h
15
qpkg/id.h
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user