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
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:
@@ -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,
|
||||
|
Reference in New Issue
Block a user