introduce got_object_idset_remove_random()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
diff --git a/lib/got_lib_object_idset.h b/lib/got_lib_object_idset.h
index 68c9c90..f5c7fb0 100644
--- a/lib/got_lib_object_idset.h
+++ b/lib/got_lib_object_idset.h
@@ -24,6 +24,8 @@ const struct got_error *got_object_idset_add(void **,
void *got_object_idset_get(struct got_object_idset *, struct got_object_id *);
const struct got_error *got_object_idset_remove(struct got_object_idset *,
struct got_object_id *);
+const struct got_error *got_object_idset_remove_random(void **,
+ struct got_object_idset *);
int got_object_idset_contains(struct got_object_idset *,
struct got_object_id *);
void got_object_idset_for_each(struct got_object_idset *,
diff --git a/lib/object_idset.c b/lib/object_idset.c
index ae64f9a..12537d5 100644
--- a/lib/object_idset.c
+++ b/lib/object_idset.c
@@ -181,6 +181,34 @@ got_object_idset_remove(struct got_object_idset *set,
return got_error(GOT_ERR_NO_OBJ);
}
+const struct got_error *
+got_object_idset_remove_random(void **data, struct got_object_idset *set)
+{
+ struct got_object_idset_element *entry, *tmp;
+ int i, n;
+
+ *data = NULL;
+
+ if (set->nelem == 0)
+ return got_error(GOT_ERR_NO_OBJ);
+
+ n = arc4random_uniform(set->nelem);
+ for (i = 0; i < nitems(set->entries); i++) {
+ TAILQ_FOREACH_SAFE(entry, &set->entries[i], entry, tmp) {
+ if (--n == 0) {
+ TAILQ_REMOVE(&set->entries[i], entry, entry);
+ *data = entry->data;
+ free(entry);
+ set->nelem--;
+ return NULL;
+ }
+ }
+
+ }
+
+ return got_error(GOT_ERR_NO_OBJ);
+}
+
int
got_object_idset_contains(struct got_object_idset *set,
struct got_object_id *id)