Use uint64_t array and fewer branches in BitSet
All checks were successful
Tests / Release [gcc] total: 471, passed: 471
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap: Reference build: <a href="https://jenkins.weaselab.dev/job/weaselab/job/conflict-set/job/main/38//gcc">weaselab » conflict-set » main #38</a>
Tests / Coverage total: 469, passed: 469
weaselab/conflict-set/pipeline/head This commit looks good

This commit is contained in:
2024-02-24 18:20:00 -08:00
parent 70e3377eac
commit 0d3475e229

View File

@@ -93,62 +93,47 @@ private:
};
struct BitSet {
bool test(int i) const {
assert(0 <= i);
assert(i < 256);
if (i < 128) {
return (lo >> i) & 1;
} else {
return (hi >> (i - 128)) & 1;
}
}
void set(int i) {
assert(0 <= i);
assert(i < 256);
if (i < 128) {
lo |= __uint128_t(1) << i;
} else {
hi |= __uint128_t(1) << (i - 128);
}
}
void reset(int i) {
assert(0 <= i);
assert(i < 256);
if (i < 128) {
lo &= ~(__uint128_t(1) << i);
} else {
hi &= ~(__uint128_t(1) << (i - 128));
}
}
int firstSetGeq(int i) const {
assert(0 <= i);
if (i >= 256) {
return -1;
}
if (i < 128) {
int a = std::countr_zero(lo >> i);
if (a < 128) {
assert(i + a < 128);
return i + a;
}
i = 128;
}
int b = std::countr_zero(hi >> (i - 128));
if (b < 128) {
assert(i + b < 256);
return i + b;
}
return -1;
}
bool test(int i) const;
void set(int i);
void reset(int i);
int firstSetGeq(int i) const;
private:
__uint128_t lo = 0;
__uint128_t hi = 0;
uint64_t words[4] = {};
};
bool BitSet::test(int i) const {
assert(0 <= i);
assert(i < 256);
return words[i >> 6] & (uint64_t(1) << (i & 63));
}
void BitSet::set(int i) {
assert(0 <= i);
assert(i < 256);
words[i >> 6] |= uint64_t(1) << (i & 63);
}
void BitSet::reset(int i) {
assert(0 <= i);
assert(i < 256);
words[i >> 6] &= ~(uint64_t(1) << (i & 63));
}
int BitSet::firstSetGeq(int i) const {
assert(0 <= i);
// i may be >= 256
uint64_t mask = uint64_t(-1) << (i & 63);
for (int j = i >> 6; j < 4; ++j) {
uint64_t masked = mask & words[j];
if (masked) {
return (j << 6) + std::countr_zero(masked);
}
mask = -1;
}
return -1;
}
enum class Type : int8_t {
Node4,
Node16,