Date:2010-11-20 01:17:08 (8 years 10 months ago)
Author:Werner Almesberger
Commit:e1814ce372d6d7e0df001226bd74254c9ac43b6a
Message: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
Files: qpkg/Makefile (1 diff)
qpkg/TODO (1 diff)
qpkg/id.c (4 diffs)
qpkg/id.h (1 diff)

Change Details

qpkg/Makefile
22# -O, so that we get data flow analysis, which helps to find more bugs
33#LDFLAGS=-pg
44
5OBJS = gobble.o id.o prereq.o qpkg.o
5OBJS = gobble.o id.o prereq.o qpkg.o jrb.o
66OBJS_rbtest = rbtest.o jrb.o
77
88all: qpkg rbtest
qpkg/TODO
88
99  So the tree is clearly degenerated.
1010
11  Update: after switching to red-black trees, we get only 1497604 calls
12  to comp_id. This is 130% of the "good case" estimate above. Insertion
13  of a new node is currently done with two lookup, so we'll get rid of
14  some more lookups after further optimization.
1115
1216- check whether introducing a new package would cause a conflict
1317
qpkg/id.c
44#include "id.h"
55
66
7#define NODE2ID(n) ((struct id *) n)
8
9
107static struct id *free_id = NULL;
118
129
...... 
2825
2926    tree = alloc_type(struct tree);
3027    tree->comp = comp;
31    tree->root = NULL;
28    tree->root = make_jrb();
3229    return tree;
3330}
3431
3532
36static struct node *add_node(struct tree *tree, struct node *node)
37{
38    struct node **p, *last;
39    int cmp;
40
41    p = &tree->root;
42    last = NULL;
43    while (*p) {
44        last = *p;
45        cmp = tree->comp(NODE2ID(node), NODE2ID(*p));
46        if (cmp < 0)
47            p = &(*p)->left;
48        else if (cmp > 0)
49            p = &(*p)->right;
50        else
51            return *p;
52    }
53    *p = node;
54    node->up = last;
55    node->left = node->right = NULL;
56    return NULL;
57}
58
59
6033struct id *make_id(struct tree *tree, const char *s, size_t len)
6134{
6235    struct id *id;
63    struct node *node;
36    struct jrb *node;
6437
6538    if (!free_id)
6639        free_id = alloc_type(struct id);
...... 
6841    id->s = s;
6942    id->len = len;
7043    id->value = NULL;
71    node = add_node(tree, &id->node);
44    node = jrb_find(tree->root, id, tree->comp);
7245    if (node)
73        return NODE2ID(node);
46        return node->key;
47    id->jrb = jrb_insert(tree->root, id, NULL, tree->comp);
7448    free_id = NULL;
7549    return id;
7650}
...... 
8256        .s = s,
8357        .len = len
8458    };
85    const struct node *n = tree->root;
86    int cmp;
59    struct jrb *node;
8760
88    while (n) {
89        cmp = tree->comp(&id, NODE2ID(n));
90        if (cmp < 0)
91            n = n->left;
92        else if (cmp > 0)
93            n = n->right;
94        else
95            return NODE2ID(n);
96    }
97    return NULL;
61    node = jrb_find(tree->root, &id, tree->comp);
62    return node ? node->key : NULL;
9863}
9964
10065
10166const struct id *first_id(const struct tree *tree)
10267{
103    const struct node *n = tree->root;
68    struct jrb *node;
10469
105    if (!n)
106        return NULL;
107    while (n->left)
108        n = n->left;
109    return NODE2ID(n);
70    node = jrb_first(tree->root);
71    return node ? node->key : NULL;
11072}
11173
11274
11375const struct id *next_id(const struct id *id)
11476{
115    const struct node *n = &id->node;
116
117    if (n->right) {
118        n = n->right;
119        while (n->left)
120            n = n->left;
121        return NODE2ID(n);
122    }
123    while (n->up) {
124        if (n == n->up->left)
125            return NODE2ID(n->up);
126        n = n->up;
127    }
128    return NULL;
77    struct jrb *next;
78
79    next = jrb_next(id->jrb);
80    return next ? next->key : NULL;
12981}
qpkg/id.h
33
44#include <sys/types.h>
55
6#include "jrb.h"
67
7struct id;
8
9/*
10 * @@@ basic binary trees are not a good choice. should use rb.
11 * To ease future migration, we separate the node structure from the rest.
12 */
138
14struct node {
15    struct node *up, *left, *right;
16};
9struct id;
1710
1811struct tree {
1912    int (*comp)(const struct id *a, const struct id *b);
20    struct node *root;
13    struct jrb *root;
2114};
2215
2316struct id {
24    struct node node;
17    struct jrb *jrb;
2518    const char *s;
2619    size_t len;
2720    void *value;

Archive Download the corresponding diff file

Branches:
master



interactive