From e3964ccd2841b2e0659c376214f5d2b8df54ddc7 Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Sat, 19 Nov 2016 11:13:50 +0100 Subject: [PATCH] [WIP] libsepol: optimize ebitmap_cardinality() Make it linear in the bitmap size instead of quadratic --- libsepol/src/ebitmap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c index e00b9bf910..eebec314b1 100644 --- a/libsepol/src/ebitmap.c +++ b/libsepol/src/ebitmap.c @@ -125,12 +125,22 @@ int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int ma return 0; } +#include unsigned int ebitmap_cardinality(ebitmap_t *e1) { unsigned int i, count = 0; + ebitmap_node_t *n; + + for (n = e1->node; n; n = n->next) { + count += __builtin_popcountll(n->map); + } + +/* for testing the optimisation: keep the old inefficient implementation and verify equality */ + unsigned int count2 = 0; for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++) if (ebitmap_get_bit(e1, i)) - count++; + count2++; + assert(count2 == count); return count; }