Skip to content

Commit

Permalink
Implement a rolling version of countBits for the bitmap.
Browse files Browse the repository at this point in the history
  • Loading branch information
deadalnix committed Dec 6, 2023
1 parent 675aceb commit 79cbe92
Showing 1 changed file with 68 additions and 7 deletions.
75 changes: 68 additions & 7 deletions sdlib/d/gc/bitmap.d
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@ public:
return;
}

setBits(bits[i], ulong.max << offset);

static next(ref uint i) {
i++;

Expand All @@ -261,6 +259,7 @@ public:
}
}

setBits(bits[i], ulong.max << offset);
next(i);
length += offset;
length -= NimbleSize;
Expand Down Expand Up @@ -307,8 +306,6 @@ public:
return;
}

setBits(bits[i], source.bits[i], ulong.max << offset);

static next(ref uint i) {
i++;

Expand All @@ -317,6 +314,7 @@ public:
}
}

setBits(bits[i], source.bits[i], ulong.max << offset);
next(i);
length += offset;
length -= NimbleSize;
Expand All @@ -333,10 +331,18 @@ public:
}

uint countBits(uint index, uint length) const {
return countBitsImpl!false(index, length);
}

uint rollingCountBits(uint index, uint length) const {
return countBitsImpl!true(index, length);
}

uint countBitsImpl(bool IsRolling)(uint index, uint length) const {
// FIXME: in contracts.
assert(index < N);
assert(length <= N);
assert(index + length <= N);
assert(IsRolling || index + length <= N);

if (length == 0) {
return 0;
Expand All @@ -352,14 +358,24 @@ public:
return popCount(bits[i] & mask);
}

static next(ref uint i) {
i++;

if (IsRolling) {
i %= NimbleCount;
}
}

auto mask = ulong.max << offset;
uint count = popCount(bits[i++] & mask);
uint count = popCount(bits[i] & mask);

next(i);
length += offset;
length -= NimbleSize;

while (length > NimbleSize) {
count += popCount(bits[i++]);
count += popCount(bits[i]);
next(i);
length -= NimbleSize;
}

Expand Down Expand Up @@ -870,3 +886,48 @@ unittest countBits {
assert(bmp.countBits(i, 128) == 64);
}
}

unittest rollingCountBits {
Bitmap!256 bmp;
foreach (i; 0 .. 256) {
assert(bmp.rollingCountBits(i, 0) == 0);
assert(bmp.rollingCountBits(i, 19) == 0);
assert(bmp.rollingCountBits(i, 48) == 0);
assert(bmp.rollingCountBits(i, 64) == 0);
assert(bmp.rollingCountBits(i, 99) == 0);
assert(bmp.rollingCountBits(i, 128) == 0);
assert(bmp.rollingCountBits(i, 137) == 0);
assert(bmp.rollingCountBits(i, 192) == 0);
assert(bmp.rollingCountBits(i, 255) == 0);
assert(bmp.rollingCountBits(i, 256) == 0);
}

bmp.bits = [-1, -1, -1, -1];
foreach (i; 0 .. 256) {
assert(bmp.rollingCountBits(i, 0) == 0);
assert(bmp.rollingCountBits(i, 19) == 19);
assert(bmp.rollingCountBits(i, 48) == 48);
assert(bmp.rollingCountBits(i, 64) == 64);
assert(bmp.rollingCountBits(i, 99) == 99);
assert(bmp.rollingCountBits(i, 128) == 128);
assert(bmp.rollingCountBits(i, 137) == 137);
assert(bmp.rollingCountBits(i, 192) == 192);
assert(bmp.rollingCountBits(i, 255) == 255);
assert(bmp.rollingCountBits(i, 256) == 256);
}

bmp.bits = [0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa,
0xaaaaaaaaaaaaaaaa];
foreach (i; 0 .. 256) {
assert(bmp.rollingCountBits(i, 0) == 0);
assert(bmp.rollingCountBits(i, 19) == 9 + (i % 2));
assert(bmp.rollingCountBits(i, 48) == 24);
assert(bmp.rollingCountBits(i, 64) == 32);
assert(bmp.rollingCountBits(i, 99) == 49 + (i % 2));
assert(bmp.rollingCountBits(i, 128) == 64);
assert(bmp.rollingCountBits(i, 137) == 68 + (i % 2));
assert(bmp.rollingCountBits(i, 192) == 96);
assert(bmp.rollingCountBits(i, 255) == 127 + (i % 2));
assert(bmp.rollingCountBits(i, 256) == 128);
}
}

0 comments on commit 79cbe92

Please sign in to comment.