/* * Look up the record for the given sha1 in the hash map stored in * obj_hash. Return NULL if it was not found. */ struct object *lookup_object(const unsigned char *sha1) { unsigned int i, first; struct object *obj; if (!obj_hash) return NULL; first = i = hash_obj(sha1, obj_hash_size); while ((obj = obj_hash[i]) != NULL) { if (!hashcmp(sha1, obj->oid.hash)) break; i++; if (i == obj_hash_size) i = 0; } if (obj && i != first) { /* * Move object to where we started to look for it so * that we do not need to walk the hash table the next * time we look for it. */ SWAP(obj_hash[i], obj_hash[first]); } return obj; }
/* * Insert obj into the hash table hash, which has length size (which * must be a power of 2). On collisions, simply overflow to the next * empty bucket. */ static void insert_obj_hash(struct object *obj, struct object **hash, unsigned int size) { unsigned int j = hash_obj(obj->oid.hash, size); while (hash[j]) { j++; if (j >= size) j = 0; } hash[j] = obj; }
/* Lookup a decoration pointer */ void *lookup_decoration(struct decoration *n, const struct object *obj) { unsigned int j; /* nothing to lookup */ if (!n->size) return NULL; j = hash_obj(obj, n->size); for (;;) { struct object_decoration *ref = n->hash + j; if (ref->base == obj) return ref->decoration; if (!ref->base) return NULL; if (++j == n->size) j = 0; } }
static void *insert_decoration(struct decoration *n, const struct object *base, void *decoration) { int size = n->size; struct object_decoration *hash = n->hash; unsigned int j = hash_obj(base, size); while (hash[j].base) { if (hash[j].base == base) { void *old = hash[j].decoration; hash[j].decoration = decoration; return old; } if (++j >= size) j = 0; } hash[j].base = base; hash[j].decoration = decoration; n->nr++; return NULL; }