2 * A wrapper around cbtree which stores oids
3 * May be used to replace oid-array for prefix (abbreviation) matches
9 struct oidtree_iter_data
{
12 size_t *last_nibble_at
;
17 void oidtree_init(struct oidtree
*ot
)
20 mem_pool_init(&ot
->mem_pool
, 0);
23 void oidtree_clear(struct oidtree
*ot
)
26 mem_pool_discard(&ot
->mem_pool
, 0);
31 void oidtree_insert(struct oidtree
*ot
, const struct object_id
*oid
)
36 BUG("oidtree_insert requires oid->algo");
38 on
= mem_pool_alloc(&ot
->mem_pool
, sizeof(*on
) + sizeof(*oid
));
39 oidcpy_with_padding((struct object_id
*)on
->k
, oid
);
42 * n.b. Current callers won't get us duplicates, here. If a
43 * future caller causes duplicates, there'll be a a small leak
44 * that won't be freed until oidtree_clear. Currently it's not
45 * worth maintaining a free list
47 cb_insert(&ot
->tree
, on
, sizeof(*oid
));
51 int oidtree_contains(struct oidtree
*ot
, const struct object_id
*oid
)
54 size_t klen
= sizeof(k
);
56 oidcpy_with_padding(&k
, oid
);
58 if (oid
->algo
== GIT_HASH_UNKNOWN
)
59 klen
-= sizeof(oid
->algo
);
61 /* cb_lookup relies on memcmp on the struct, so order matters: */
62 klen
+= BUILD_ASSERT_OR_ZERO(offsetof(struct object_id
, hash
) <
63 offsetof(struct object_id
, algo
));
65 return cb_lookup(&ot
->tree
, (const uint8_t *)&k
, klen
) ? 1 : 0;
68 static enum cb_next
iter(struct cb_node
*n
, void *arg
)
70 struct oidtree_iter_data
*x
= arg
;
71 const struct object_id
*oid
= (const struct object_id
*)n
->k
;
73 if (x
->algo
!= GIT_HASH_UNKNOWN
&& x
->algo
!= oid
->algo
)
76 if (x
->last_nibble_at
) {
77 if ((oid
->hash
[*x
->last_nibble_at
] ^ x
->last_byte
) & 0xf0)
81 return x
->fn(oid
, x
->arg
);
84 void oidtree_each(struct oidtree
*ot
, const struct object_id
*oid
,
85 size_t oidhexsz
, oidtree_iter fn
, void *arg
)
87 size_t klen
= oidhexsz
/ 2;
88 struct oidtree_iter_data x
= { 0 };
89 assert(oidhexsz
<= GIT_MAX_HEXSZ
);
95 x
.last_byte
= oid
->hash
[klen
];
96 x
.last_nibble_at
= &klen
;
98 cb_each(&ot
->tree
, (const uint8_t *)oid
, klen
, iter
, &x
);