util/sparse_bitset: add u_sparse_bitset_clear_all

It is sometimes useful to remove all elements of a bitset while retaining the
backing storage. With a dense bitset, we would just memset everything to 0,
which is O(capacity). With a sparse bitset, previously we would have to free and
reallocate, which is O(capacity) in the dense case and O(cardinality) in the
sparse case. That is the correct asymptoptic behaviour O(cardinality) in the
worst case, but there is an unfortunate constant-factor associated with the
redundant allocation & free in the dense case.

Therefore, we add a new helper to clear all elements of the sparse bitset in one
go, avoiding reallocation in the dense case.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Natalie Vock <natalie.vock@gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40806>
This commit is contained in:
Alyssa Rosenzweig 2026-04-06 08:59:07 -04:00 committed by Marge Bot
parent 994ead31bd
commit dbb7050ca7

View file

@ -77,6 +77,19 @@ u_sparse_bitset_init(struct u_sparse_bitset *s, unsigned capacity,
}
}
static inline void
u_sparse_bitset_clear_all(struct u_sparse_bitset *s)
{
if (_u_sparse_bitset_is_small(s)) {
memset(s->vals, 0, BITSET_BYTES(s->capacity));
} else {
rb_tree_foreach_safe(struct u_sparse_bitset_node, node, &s->tree, node) {
rb_tree_remove(&s->tree, &node->node);
ralloc_free(node);
}
}
}
static inline int
_u_sparse_bitset_node_comparator(const struct rb_node *a, unsigned offset_b)
{