qpkg: optimize duplicate lookup when inserting a new name

- jrb.h, jrb.c (jrb_find_or_insert): new function to look for a node and
  to insert a new one if not found
- id.c (make_id): use jrb_find_or_insert to avoid looking up new nodes
  twice
- TODO: report the improvement
This commit is contained in:
Werner Almesberger 2010-11-19 22:20:15 -03:00
parent 64c70e77f4
commit 03c5e4ffe7
4 changed files with 24 additions and 6 deletions

View File

@ -10,9 +10,12 @@
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
of a new node is currently done with two lookups, so we'll get rid of
some more lookups after further optimization.
Update: after merging the two lookups per new node into one, we're at
1172642 calls to comp_id, or 102% of the predicted "good case".
- check whether introducing a new package would cause a conflict
- compile the list of conflicts of installed packages

View File

@ -38,17 +38,15 @@ struct tree *make_tree(int (*comp)(const void *a, const void *b))
struct id *make_id(struct tree *tree, const char *s, size_t len)
{
struct id *id;
struct jrb *node;
if (!free_id)
free_id = alloc_type(struct id);
id = free_id;
id->s = s;
id->len = len;
node = jrb_find(tree->root, id, tree->comp);
if (node)
return node->key;
id->jrb = jrb_insert(tree->root, id, NULL, tree->comp);
id->jrb = jrb_find_or_insert(tree->root, id, NULL, tree->comp);
if (id->jrb->key != id)
return id->jrb->key;
free_id = NULL;
return id;
}

View File

@ -552,3 +552,14 @@ struct jrb *jrb_insert(struct jrb *tree, void *key, void *val,
return jrb_insert_b(jrb_find_gte(tree, key, func, &fnd), key, val);
}
struct jrb *jrb_find_or_insert(struct jrb *tree, void *key, void *val,
int (*func)(const void *a, const void *b))
{
struct jrb *n;
int fnd;
n = jrb_find_gte(tree, key, func, &fnd);
return fnd ? n : jrb_insert_b(n, key, val);
}

View File

@ -72,6 +72,12 @@ struct jrb *make_jrb(void); /* Creates a new rb-tree */
struct jrb *jrb_insert(struct jrb *tree, void *key, void *val,
int (*func)(const void *a, const void *b));
/* If the key already exists, return the node (without altering it).
Otherwise, insert a new node. */
struct jrb *jrb_find_or_insert(struct jrb *tree, void *key, void *val,
int (*func)(const void *a, const void *b));
/* returns an external node in t whose value is equal k. Returns NULL if
there is no such node in the tree */