void reset() {
block_ = (bits_ != nullptr) ? folly::loadUnaligned<uint64_t>(bits_) : 0;
outer_ = 0;
- inner_ = -1;
position_ = -1;
value_ = kInvalidValue;
}
}
++position_;
- inner_ = Instructions::ctz(block_);
+ auto inner = Instructions::ctz(block_);
block_ = Instructions::blsr(block_);
- return setValue();
+ return setValue(inner);
}
bool skip(size_t n) {
reposition(dest);
n = position_ + 1 - steps * Encoder::forwardQuantum;
- // Correct inner_ will be set at the end.
}
size_t cnt;
// Skip to the n-th one in the block.
DCHECK_GT(n, 0);
- inner_ = select64<Instructions>(block_, n - 1);
- block_ &= (uint64_t(-1) << inner_) << 1;
+ auto inner = select64<Instructions>(block_, n - 1);
+ block_ &= (uint64_t(-1) << inner) << 1;
- return setValue();
+ return setValue(inner);
}
bool skipTo(ValueType v) {
block_ = folly::loadUnaligned<uint64_t>(bits_ + outer_);
}
- inner_ = Instructions::ctz(block_);
+ auto inner = Instructions::ctz(block_);
block_ = Instructions::blsr(block_);
- setValue();
+ setValue(inner);
return true;
}
constexpr static ValueType kInvalidValue =
std::numeric_limits<ValueType>::max(); // Must hold kInvalidValue + 1 == 0.
- bool setValue() {
- value_ = static_cast<ValueType>(8 * outer_ + inner_);
+ bool setValue(size_t inner) {
+ value_ = static_cast<ValueType>(8 * outer_ + inner);
return true;
}
constexpr static size_t kLinearScanThreshold = 4;
size_t outer_;
- size_t inner_;
size_t position_;
uint64_t block_;
ValueType value_;
void reset() {
block_ = start_ != nullptr ? folly::loadUnaligned<block_t>(start_) : 0;
outer_ = 0;
- inner_ = std::numeric_limits<size_t>::max();
position_ = std::numeric_limits<size_t>::max();
value_ = 0;
}
}
++position_;
- inner_ = size_t(Instructions::ctz(block_));
+ size_t inner = Instructions::ctz(block_);
block_ = Instructions::blsr(block_);
- return setValue();
+ return setValue(inner);
}
ValueType skip(size_t n) {
reposition(dest + steps * Encoder::forwardQuantum);
n = position_ + 1 - steps * Encoder::forwardQuantum; // n is > 0.
- // Correct inner_ will be set at the end.
}
size_t cnt;
// Skip to the n-th one in the block.
DCHECK_GT(n, 0);
- inner_ = select64<Instructions>(block_, n - 1);
- block_ &= (block_t(-1) << inner_) << 1;
+ size_t inner = select64<Instructions>(block_, n - 1);
+ block_ &= (block_t(-1) << inner) << 1;
- return setValue();
+ return setValue(inner);
}
// Skip to the first element that is >= v and located *after* the current
reposition(dest + Encoder::skipQuantum * steps);
position_ = dest - 1;
- // Correct inner_ and value_ will be set during the next()
- // call at the end.
+ // Correct value_ will be set during the next() call at the end.
// NOTE: Corresponding block of lower bits sequence may be
// prefetched here (via __builtin_prefetch), but experiments
DCHECK_GT(position(), 0);
size_t outer = outer_;
+ auto inner = size_t(value_) - 8 * outer_ + position_;
block_t block = folly::loadUnaligned<block_t>(start_ + outer);
- block &= (block_t(1) << inner_) - 1;
+ block &= (block_t(1) << inner) - 1;
while (UNLIKELY(block == 0)) {
DCHECK_GT(outer, 0);
block = folly::loadUnaligned<block_t>(start_ + outer);
}
- auto inner = 8 * sizeof(block_t) - 1 - Instructions::clz(block);
+ inner = 8 * sizeof(block_t) - 1 - Instructions::clz(block);
return static_cast<ValueType>(8 * outer + inner - (position_ - 1));
}
}
private:
- ValueType setValue() {
- value_ = static_cast<ValueType>(8 * outer_ + inner_ - position_);
+ ValueType setValue(size_t inner) {
+ value_ = static_cast<ValueType>(8 * outer_ + inner - position_);
return value_;
}
const unsigned char* const start_;
block_t block_;
size_t outer_; // Outer offset: number of consumed bytes in upper.
- size_t inner_; // Inner offset: (bit) position in current block.
size_t position_; // Index of current value (= #reads - 1).
ValueType value_;
};