mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-22 02:44:39 +02:00
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:
parent
64c70e77f4
commit
03c5e4ffe7
@ -10,9 +10,12 @@
|
|||||||
|
|
||||||
Update: after switching to red-black trees, we get only 1497604 calls
|
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
|
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.
|
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
|
- check whether introducing a new package would cause a conflict
|
||||||
|
|
||||||
- compile the list of conflicts of installed packages
|
- compile the list of conflicts of installed packages
|
||||||
|
@ -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 *make_id(struct tree *tree, const char *s, size_t len)
|
||||||
{
|
{
|
||||||
struct id *id;
|
struct id *id;
|
||||||
struct jrb *node;
|
|
||||||
|
|
||||||
if (!free_id)
|
if (!free_id)
|
||||||
free_id = alloc_type(struct id);
|
free_id = alloc_type(struct id);
|
||||||
id = free_id;
|
id = free_id;
|
||||||
id->s = s;
|
id->s = s;
|
||||||
id->len = len;
|
id->len = len;
|
||||||
node = jrb_find(tree->root, id, tree->comp);
|
id->jrb = jrb_find_or_insert(tree->root, id, NULL, tree->comp);
|
||||||
if (node)
|
if (id->jrb->key != id)
|
||||||
return node->key;
|
return id->jrb->key;
|
||||||
id->jrb = jrb_insert(tree->root, id, NULL, tree->comp);
|
|
||||||
free_id = NULL;
|
free_id = NULL;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
11
qpkg/jrb.c
11
qpkg/jrb.c
@ -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);
|
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);
|
||||||
|
}
|
||||||
|
@ -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,
|
struct jrb *jrb_insert(struct jrb *tree, void *key, void *val,
|
||||||
int (*func)(const void *a, const void *b));
|
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
|
/* returns an external node in t whose value is equal k. Returns NULL if
|
||||||
there is no such node in the tree */
|
there is no such node in the tree */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user