compat: Add simplified merge sort implementation from glibc
[gitweb.git] / object-refs.c
index 98ea10005a851c3879c6e65929e3e34068dc9e8b..5345671569e9500ad31124dacf9525739687d9be 100644 (file)
@@ -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)
@@ -140,5 +85,3 @@ void mark_reachable(struct object *obj, unsigned int mask)
                        mark_reachable(refs->ref[i], mask);
        }
 }
-
-