]>
Commit | Line | Data |
---|---|---|
1 | #include "cache.h" | |
2 | #include "sha1-array.h" | |
3 | #include "sha1-lookup.h" | |
4 | ||
5 | void oid_array_append(struct oid_array *array, const struct object_id *oid) | |
6 | { | |
7 | ALLOC_GROW(array->oid, array->nr + 1, array->alloc); | |
8 | oidcpy(&array->oid[array->nr++], oid); | |
9 | array->sorted = 0; | |
10 | } | |
11 | ||
12 | static int void_hashcmp(const void *a, const void *b) | |
13 | { | |
14 | return oidcmp(a, b); | |
15 | } | |
16 | ||
17 | static void oid_array_sort(struct oid_array *array) | |
18 | { | |
19 | QSORT(array->oid, array->nr, void_hashcmp); | |
20 | array->sorted = 1; | |
21 | } | |
22 | ||
23 | static const unsigned char *sha1_access(size_t index, void *table) | |
24 | { | |
25 | struct object_id *array = table; | |
26 | return array[index].hash; | |
27 | } | |
28 | ||
29 | int oid_array_lookup(struct oid_array *array, const struct object_id *oid) | |
30 | { | |
31 | if (!array->sorted) | |
32 | oid_array_sort(array); | |
33 | return sha1_pos(oid->hash, array->oid, array->nr, sha1_access); | |
34 | } | |
35 | ||
36 | void oid_array_clear(struct oid_array *array) | |
37 | { | |
38 | FREE_AND_NULL(array->oid); | |
39 | array->nr = 0; | |
40 | array->alloc = 0; | |
41 | array->sorted = 0; | |
42 | } | |
43 | ||
44 | ||
45 | int oid_array_for_each(struct oid_array *array, | |
46 | for_each_oid_fn fn, | |
47 | void *data) | |
48 | { | |
49 | int i; | |
50 | ||
51 | /* No oid_array_sort() here! See the api-oid-array.txt docs! */ | |
52 | ||
53 | for (i = 0; i < array->nr; i++) { | |
54 | int ret = fn(array->oid + i, data); | |
55 | if (ret) | |
56 | return ret; | |
57 | } | |
58 | return 0; | |
59 | } | |
60 | ||
61 | int oid_array_for_each_unique(struct oid_array *array, | |
62 | for_each_oid_fn fn, | |
63 | void *data) | |
64 | { | |
65 | int i; | |
66 | ||
67 | if (!array->sorted) | |
68 | oid_array_sort(array); | |
69 | ||
70 | for (i = 0; i < array->nr; i++) { | |
71 | int ret; | |
72 | if (i > 0 && oideq(array->oid + i, array->oid + i - 1)) | |
73 | continue; | |
74 | ret = fn(array->oid + i, data); | |
75 | if (ret) | |
76 | return ret; | |
77 | } | |
78 | return 0; | |
79 | } | |
80 | ||
81 | void oid_array_filter(struct oid_array *array, | |
82 | for_each_oid_fn want, | |
83 | void *cb_data) | |
84 | { | |
85 | unsigned nr = array->nr, src, dst; | |
86 | struct object_id *oids = array->oid; | |
87 | ||
88 | for (src = dst = 0; src < nr; src++) { | |
89 | if (want(&oids[src], cb_data)) { | |
90 | if (src != dst) | |
91 | oidcpy(&oids[dst], &oids[src]); | |
92 | dst++; | |
93 | } | |
94 | } | |
95 | array->nr = dst; | |
96 | } |