commit 27c21a117aca21c6059c735e8aed46d0c27d01bd from: Stefan Sperling date: Fri Jun 22 07:30:25 2018 UTC introduce got_object_idset_remove_random() 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)