Signed-off-by: Stefan Beller <sbel...@google.com>
---
 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

Reply via email to