Commit Diff


commit - ac4e69fbc9b15eb4f36baa8a21c92ba3afe81cc8
commit + 27c21a117aca21c6059c735e8aed46d0c27d01bd
blob - 68c9c90e1ee5d379791a817a91cc2d2fd6307579
blob + f5c7fb0f00c0573570366492dace80e6a2640ea1
--- lib/got_lib_object_idset.h
+++ 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 *,
blob - ae64f9afe555ae449ffadfb4d39015675ba0b35b
blob + 12537d598a09fb6811e21b5ce3b0579684a0dabe
--- lib/object_idset.c
+++ 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)