Git fork
at reftables-rust 96 lines 2.0 kB view raw
1/* 2 * decorate.c - decorate a git object with some arbitrary 3 * data. 4 */ 5 6#include "git-compat-util.h" 7#include "object.h" 8#include "decorate.h" 9 10static unsigned int hash_obj(const struct object *obj, unsigned int n) 11{ 12 return oidhash(&obj->oid) % n; 13} 14 15static void *insert_decoration(struct decoration *n, const struct object *base, void *decoration) 16{ 17 struct decoration_entry *entries = n->entries; 18 unsigned int j = hash_obj(base, n->size); 19 20 while (entries[j].base) { 21 if (entries[j].base == base) { 22 void *old = entries[j].decoration; 23 entries[j].decoration = decoration; 24 return old; 25 } 26 if (++j >= n->size) 27 j = 0; 28 } 29 entries[j].base = base; 30 entries[j].decoration = decoration; 31 n->nr++; 32 return NULL; 33} 34 35static void grow_decoration(struct decoration *n) 36{ 37 unsigned int i; 38 unsigned int old_size = n->size; 39 struct decoration_entry *old_entries = n->entries; 40 41 n->size = (old_size + 1000) * 3 / 2; 42 CALLOC_ARRAY(n->entries, n->size); 43 n->nr = 0; 44 45 for (i = 0; i < old_size; i++) { 46 const struct object *base = old_entries[i].base; 47 void *decoration = old_entries[i].decoration; 48 49 if (!decoration) 50 continue; 51 insert_decoration(n, base, decoration); 52 } 53 free(old_entries); 54} 55 56void *add_decoration(struct decoration *n, const struct object *obj, 57 void *decoration) 58{ 59 if ((n->nr + 1) > n->size * 2 / 3) 60 grow_decoration(n); 61 return insert_decoration(n, obj, decoration); 62} 63 64void *lookup_decoration(struct decoration *n, const struct object *obj) 65{ 66 unsigned int j; 67 68 /* nothing to lookup */ 69 if (!n->size) 70 return NULL; 71 j = hash_obj(obj, n->size); 72 for (;;) { 73 struct decoration_entry *ref = n->entries + j; 74 if (ref->base == obj) 75 return ref->decoration; 76 if (!ref->base) 77 return NULL; 78 if (++j == n->size) 79 j = 0; 80 } 81} 82 83void clear_decoration(struct decoration *n, void (*free_cb)(void *)) 84{ 85 if (free_cb) { 86 unsigned int i; 87 for (i = 0; i < n->size; i++) { 88 void *d = n->entries[i].decoration; 89 if (d) 90 free_cb(d); 91 } 92 } 93 94 FREE_AND_NULL(n->entries); 95 n->size = n->nr = 0; 96}