summaryrefslogtreecommitdiff
path: root/object-refs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2007-04-16 23:03:15 (GMT)
committerJunio C Hamano <junkio@cox.net>2007-04-16 23:51:09 (GMT)
commita59b276e18f3d4a548caf549e05188cb1bd3a709 (patch)
tree2633d6fd7b33dddee9c1d7ed35d6061bffc957ba /object-refs.c
parent402fa75eed29c104ae5392ce88560f6bffc64ce7 (diff)
downloadgit-a59b276e18f3d4a548caf549e05188cb1bd3a709.zip
git-a59b276e18f3d4a548caf549e05188cb1bd3a709.tar.gz
git-a59b276e18f3d4a548caf549e05188cb1bd3a709.tar.bz2
Add a generic "object decorator" interface, and make object refs use it
This allows you to add an arbitrary "decoration" of your choice to any object. It's a space- and time-efficient way to add information to arbitrary objects, especially if most objects probably do not have the decoration. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'object-refs.c')
-rw-r--r--object-refs.c69
1 files changed, 7 insertions, 62 deletions
diff --git a/object-refs.c b/object-refs.c
index 98ea100..022e8d8 100644
--- a/object-refs.c
+++ b/object-refs.c
@@ -1,75 +1,20 @@
#include "cache.h"
#include "object.h"
+#include "decorate.h"
int track_object_refs = 0;
-static unsigned int refs_hash_size, nr_object_refs;
-static struct object_refs **refs_hash;
+static struct decoration ref_decorate;
-static unsigned int hash_obj(struct object *obj, unsigned int n)
+struct object_refs *lookup_object_refs(struct object *base)
{
- unsigned int hash = *(unsigned int *)obj->sha1;
- return hash % n;
+ return lookup_decoration(&ref_decorate, base);
}
-static void insert_ref_hash(struct object_refs *ref, struct object_refs **hash, unsigned int size)
+static void add_object_refs(struct object *obj, struct object_refs *refs)
{
- int j = hash_obj(ref->base, size);
-
- while (hash[j]) {
- j++;
- if (j >= size)
- j = 0;
- }
- hash[j] = ref;
-}
-
-static void grow_refs_hash(void)
-{
- int i;
- int new_hash_size = (refs_hash_size + 1000) * 3 / 2;
- struct object_refs **new_hash;
-
- new_hash = xcalloc(new_hash_size, sizeof(struct object_refs *));
- for (i = 0; i < refs_hash_size; i++) {
- struct object_refs *ref = refs_hash[i];
- if (!ref)
- continue;
- insert_ref_hash(ref, new_hash, new_hash_size);
- }
- free(refs_hash);
- refs_hash = new_hash;
- refs_hash_size = new_hash_size;
-}
-
-static void add_object_refs(struct object *obj, struct object_refs *ref)
-{
- int nr = nr_object_refs + 1;
-
- if (nr > refs_hash_size * 2 / 3)
- grow_refs_hash();
- ref->base = obj;
- insert_ref_hash(ref, refs_hash, refs_hash_size);
- nr_object_refs = nr;
-}
-
-struct object_refs *lookup_object_refs(struct object *obj)
-{
- struct object_refs *ref;
- int j;
-
- /* nothing to lookup */
- if (!refs_hash_size)
- return NULL;
- j = hash_obj(obj, refs_hash_size);
- while ((ref = refs_hash[j]) != NULL) {
- if (ref->base == obj)
- break;
- j++;
- if (j >= refs_hash_size)
- j = 0;
- }
- return ref;
+ if (add_decoration(&ref_decorate, obj, refs))
+ die("object %s tried to add refs twice!", sha1_to_hex(obj->sha1));
}
struct object_refs *alloc_object_refs(unsigned count)