X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=object.c;h=92813001e25f20ae7dd7a1e0f0ef11ec5d746030;hb=9ccb64c8e0791a865ad520bcfff4b02cc7c50097;hp=37784cee9a90a7e5b44dd660d6b7ea9191b59486;hpb=811476d22480dd444b8eca9834829efce9648637;p=git.git diff --git a/object.c b/object.c index 37784cee9..92813001e 100644 --- a/object.c +++ b/object.c @@ -5,79 +5,98 @@ #include "commit.h" #include "tag.h" -struct object **objs; -static int nr_objs; -int obj_allocs; +static struct object **obj_hash; +static int nr_objs, obj_hash_size; + +unsigned int get_max_object_index(void) +{ + return obj_hash_size; +} + +struct object *get_indexed_object(unsigned int idx) +{ + return obj_hash[idx]; +} const char *type_names[] = { - "none", "blob", "tree", "commit", "bad" + "none", "commit", "tree", "blob", "tag", + "bad type 5", "bad type 6", "delta", "bad", }; +static unsigned int hash_obj(struct object *obj, unsigned int n) +{ + unsigned int hash = *(unsigned int *)obj->sha1; + return hash % n; +} + +static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size) +{ + int j = hash_obj(obj, size); + + while (hash[j]) { + j++; + if (j >= size) + j = 0; + } + hash[j] = obj; +} + static int hashtable_index(const unsigned char *sha1) { unsigned int i; memcpy(&i, sha1, sizeof(unsigned int)); - return (int)(i % obj_allocs); + return (int)(i % obj_hash_size); } -static int find_object(const unsigned char *sha1) +struct object *lookup_object(const unsigned char *sha1) { int i; + struct object *obj; - if (!objs) - return -1; + if (!obj_hash) + return NULL; i = hashtable_index(sha1); - while (objs[i]) { - if (memcmp(sha1, objs[i]->sha1, 20) == 0) - return i; + while ((obj = obj_hash[i]) != NULL) { + if (!hashcmp(sha1, obj->sha1)) + break; i++; - if (i == obj_allocs) + if (i == obj_hash_size) i = 0; } - return -1 - i; + return obj; } -struct object *lookup_object(const unsigned char *sha1) +static void grow_object_hash(void) { - int pos = find_object(sha1); - if (pos >= 0) - return objs[pos]; - return NULL; + int i; + int new_hash_size = obj_hash_size < 32 ? 32 : 2 * obj_hash_size; + struct object **new_hash; + + new_hash = xcalloc(new_hash_size, sizeof(struct object *)); + for (i = 0; i < obj_hash_size; i++) { + struct object *obj = obj_hash[i]; + if (!obj) + continue; + insert_obj_hash(obj, new_hash, new_hash_size); + } + free(obj_hash); + obj_hash = new_hash; + obj_hash_size = new_hash_size; } void created_object(const unsigned char *sha1, struct object *obj) { - int pos; - obj->parsed = 0; - memcpy(obj->sha1, sha1, 20); - obj->type = TYPE_NONE; obj->used = 0; + obj->type = OBJ_NONE; + obj->flags = 0; + hashcpy(obj->sha1, sha1); - if (obj_allocs - 1 <= nr_objs * 2) { - int i, count = obj_allocs; - obj_allocs = (obj_allocs < 32 ? 32 : 2 * obj_allocs); - objs = xrealloc(objs, obj_allocs * sizeof(struct object *)); - memset(objs + count, 0, (obj_allocs - count) - * sizeof(struct object *)); - for (i = 0; i < obj_allocs; i++) - if (objs[i]) { - int j = find_object(objs[i]->sha1); - if (j != i) { - j = -1 - j; - objs[j] = objs[i]; - objs[i] = NULL; - } - } - } - - pos = find_object(sha1); - if (pos >= 0) - die("Inserting %s twice\n", sha1_to_hex(sha1)); - pos = -pos-1; + if (obj_hash_size - 1 <= nr_objs * 2) + grow_object_hash(); - objs[pos] = obj; + insert_obj_hash(obj, obj_hash, obj_hash_size); nr_objs++; } @@ -113,7 +132,7 @@ struct object *lookup_unknown_object(const unsigned char *sha1) if (!obj) { union any_object *ret = xcalloc(1, sizeof(*ret)); created_object(sha1, &ret->object); - ret->object.type = TYPE_NONE; + ret->object.type = OBJ_NONE; return &ret->object; } return obj;