Signed-off-by: Stefan Beller <[email protected]>
---
sha1-array.c | 39 +++++++++++++++++++++++++++++++++++++++
sha1-array.h | 3 +++
2 files changed, 42 insertions(+)
diff --git a/sha1-array.c b/sha1-array.c
index 265941fbf40..10eb08b425e 100644
--- a/sha1-array.c
+++ b/sha1-array.c
@@ -77,3 +77,42 @@ int oid_array_for_each_unique(struct oid_array *array,
}
return 0;
}
+
+int oid_array_remove_if(struct oid_array *array,
+ for_each_oid_fn fn,
+ void *data)
+{
+ int i, j;
+ char *to_remove = xcalloc(array->nr, sizeof(char));
+
+ /* No oid_array_sort() here! See the api-oid-array.txt docs! */
+
+ for (i = 0; i < array->nr; i++) {
+ int ret = fn(array->oid + i, data);
+ if (ret)
+ to_remove[i] = 1;
+ }
+
+ i = 0, j = 0;
+ while (i < array->nr && j < array->nr) {
+ while (i < array->nr && !to_remove[i])
+ i++;
+ /* i at first marked for deletion or out */
+ if (j < i)
+ j = i;
+ while (j < array->nr && to_remove[j])
+ j++;
+ /* j > i; j at first valid after first deletion range or out */
+ if (i < array->nr && j < array->nr)
+ oidcpy(&array->oid[i], &array->oid[j]);
+ else if (i >= array->nr)
+ assert(j >= array->nr);
+ /* no pruning happened, keep original array->nr */
+ else if (j >= array->nr)
+ array->nr = i;
+ }
+
+ free(to_remove);
+
+ return 0;
+}
diff --git a/sha1-array.h b/sha1-array.h
index 232bf950172..151c7ad7f30 100644
--- a/sha1-array.h
+++ b/sha1-array.h
@@ -22,5 +22,8 @@ int oid_array_for_each(struct oid_array *array,
int oid_array_for_each_unique(struct oid_array *array,
for_each_oid_fn fn,
void *data);
+int oid_array_remove_if(struct oid_array *array,
+ for_each_oid_fn fn,
+ void *data);
#endif /* SHA1_ARRAY_H */
--
2.18.0.597.ga71716f1ad-goog