Commit a0776ffe authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook Github Bot

Reimplement EliasFanoReader::{jump,jumpTo} in terms of {skip, skipTo}

Summary:
Since D18140137 `reset()` doesn't perform any data reads, so we can simplify the implementation of the `jump*` functions to just reset the reader in case of a backward jump. The only tricky case we need to handle is when `jumpTo` is called from the middle of a run of identical values.

Delegating to `skip*` the additional benefit of inheriting the optimizations for small forward skips.

Differential Revision: D18496743

fbshipit-source-id: 73dc8b21534fba90f1ac2a924a7cebc56ffaba94
parent 60923bd6
...@@ -505,25 +505,6 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -505,25 +505,6 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
return position; return position;
} }
ValueType jump(size_t n) {
if (Encoder::forwardQuantum == 0 || n <= Encoder::forwardQuantum) {
reset();
} else {
// Avoid reading the head, skip() will reposition.
position_ = std::numeric_limits<SizeType>::max();
}
return skip(n);
}
ValueType jumpToNext(ValueType v) {
if (Encoder::skipQuantum == 0 || v < Encoder::skipQuantum) {
reset();
} else {
value_ = 0; // Avoid reading the head, skipToNext() will reposition.
}
return skipToNext(v);
}
ValueType previousValue() const { ValueType previousValue() const {
block_t block; block_t block;
size_t inner; size_t inner;
...@@ -532,6 +513,17 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>, ...@@ -532,6 +513,17 @@ class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
return static_cast<ValueType>(8 * outer + inner - (position_ - 1)); return static_cast<ValueType>(8 * outer + inner - (position_ - 1));
} }
// Returns true if we're at the beginning of the list, or previousValue() !=
// value().
bool isAtBeginningOfRun() const {
DCHECK_NE(position(), static_cast<SizeType>(-1));
if (position_ == 0) {
return true;
}
size_t bitPos = size_t(value_) + position_ - 1;
return (start_[bitPos / 8] & (1 << (bitPos % 8))) == 0;
}
void setDone(SizeType endPos) { void setDone(SizeType endPos) {
position_ = endPos; position_ = endPos;
} }
...@@ -726,25 +718,44 @@ class EliasFanoReader { ...@@ -726,25 +718,44 @@ class EliasFanoReader {
* false if n >= size(). * false if n >= size().
*/ */
bool jump(SizeType n) { bool jump(SizeType n) {
if (LIKELY(n < size_)) { if (n + 1 < upper_.position() + 1) { // Also works if position() == -1.
value_ = readLowerPart(n) | (upper_.jump(n + 1) << numLowerBits_); reset();
return true; n += 1; // Initial position is -1.
} else {
n -= upper_.position();
} }
return setDone(); return skip(n);
} }
/** /**
* Jumps to the first element >= value. The reader can be in any * Jumps to the first element >= value. The reader can be in any
* state. Returns false if no such element exists. * state. Returns false if no such element exists.
*
* If all the values in the list can be assumed distinct, setting
* assumeDistinct = true can enable some optimizations.
*/ */
bool jumpTo(ValueType value) { bool jumpTo(ValueType value, bool assumeDistinct = false) {
if (!kUnchecked && value > lastValue_) { if (value == value_) {
return setDone(); if (assumeDistinct == true) {
return true;
}
// We might be in the middle of a run, iterate backwards to the beginning.
auto valueLower = Instructions::bzhi(value_, numLowerBits_);
while (!upper_.isAtBeginningOfRun() &&
readLowerPart(upper_.position() - 1) == valueLower) {
upper_.previous();
}
return true;
} }
upper_.jumpToNext(value >> numLowerBits_); // We need to reset if we're not in the initial state and the jump is
iterateTo(value); // backwards.
return true; if (position() != static_cast<SizeType>(-1) &&
value < value_) { // If position() == size() value_ is kInvalidValue.
reset();
}
return skipTo(value);
} }
ValueType lastValue() const { ValueType lastValue() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment