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 {
|
struct BitSet {
|
||||||
bool test(int i) const {
|
bool test(int i) const;
|
||||||
assert(0 <= i);
|
void set(int i);
|
||||||
assert(i < 256);
|
void reset(int i);
|
||||||
if (i < 128) {
|
int firstSetGeq(int i) const;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
__uint128_t lo = 0;
|
uint64_t words[4] = {};
|
||||||
__uint128_t hi = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 {
|
enum class Type : int8_t {
|
||||||
Node4,
|
Node4,
|
||||||
Node16,
|
Node16,
|
||||||
|
Reference in New Issue
Block a user