experimental/ThreadedRepeatingFunctionRunner.h \
experimental/Bits.h \
experimental/BitVectorCoding.h \
+ experimental/CodingDetail.h \
experimental/DynamicParser.h \
experimental/DynamicParser-inl.h \
experimental/ExecutionObserver.h \
#include <folly/Portability.h>
#include <folly/Range.h>
#include <folly/experimental/Bits.h>
+#include <folly/experimental/CodingDetail.h>
#include <folly/experimental/Instructions.h>
#include <folly/experimental/Select64.h>
#include <glog/logging.h>
size_t forwardPointers = 0;
};
-template <class Encoder,
- class Instructions = instructions::Default,
- bool kUnchecked = false>
-class BitVectorReader {
+template <
+ class Encoder,
+ class Instructions = instructions::Default,
+ bool kUnchecked = false>
+class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>,
+ detail::SkipPointers<Encoder::skipQuantum> {
public:
typedef Encoder EncoderType;
typedef typename Encoder::ValueType ValueType;
typedef typename Encoder::SkipValueType SkipValueType;
explicit BitVectorReader(const typename Encoder::CompressedList& list)
- : size_(list.size),
+ : detail::ForwardPointers<Encoder::forwardQuantum>(list.forwardPointers),
+ detail::SkipPointers<Encoder::skipQuantum>(list.skipPointers),
bits_(list.bits),
- skipPointers_(list.skipPointers),
- forwardPointers_(list.forwardPointers) {
+ size_(list.size) {
reset();
if (kUnchecked || UNLIKELY(list.size == 0)) {
if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) {
const size_t steps = position_ / Encoder::forwardQuantum;
const size_t dest = folly::loadUnaligned<SkipValueType>(
- forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
+ this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
reposition(dest);
n = position_ + 1 - steps * Encoder::forwardQuantum;
if (Encoder::skipQuantum > 0 && v - value_ > Encoder::skipQuantum) {
size_t q = v / Encoder::skipQuantum;
auto skipPointer = folly::loadUnaligned<SkipValueType>(
- skipPointers_ + (q - 1) * sizeof(SkipValueType));
+ this->skipPointers_ + (q - 1) * sizeof(SkipValueType));
position_ = static_cast<SizeType>(skipPointer) - 1;
reposition(q * Encoder::skipQuantum);
constexpr static size_t kLinearScanThreshold = 4;
+ const uint8_t* const bits_;
uint64_t block_;
SizeType outer_;
SizeType position_;
SizeType size_;
ValueType upperBound_;
- const uint8_t* const bits_;
- const uint8_t* const skipPointers_;
- const uint8_t* const forwardPointers_;
};
}} // namespaces
--- /dev/null
+/*
+ * Copyright 2017 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Giuseppe Ottaviano <ott@fb.com>
+ *
+ * Shared utils for BitVectorCoding.h and EliasFanoCoding.h.
+ */
+
+#pragma once
+
+namespace folly {
+namespace compression {
+namespace detail {
+
+/**
+ * Helpers to store pointers to forward and skip pointer arrays only
+ * if they are used, that is, the quantum is nonzero. If it is 0, the
+ * class is empty, and the member is static to keep the syntax valid,
+ * thus it will take no space in a derived class thanks to empty base
+ * class optimization.
+ */
+template <size_t>
+class ForwardPointers {
+ protected:
+ explicit ForwardPointers(const unsigned char* ptr) : forwardPointers_(ptr) {}
+ const unsigned char* const forwardPointers_;
+};
+template <>
+class ForwardPointers<0> {
+ protected:
+ explicit ForwardPointers(const unsigned char*) {}
+ constexpr static const unsigned char* const forwardPointers_{};
+};
+
+template <size_t>
+class SkipPointers {
+ protected:
+ explicit SkipPointers(const unsigned char* ptr) : skipPointers_(ptr) {}
+ const unsigned char* const skipPointers_;
+};
+template <>
+class SkipPointers<0> {
+ protected:
+ explicit SkipPointers(const unsigned char*) {}
+ constexpr static const unsigned char* const skipPointers_{};
+};
+}
+}
+}
#include <folly/Likely.h>
#include <folly/Portability.h>
#include <folly/Range.h>
+#include <folly/experimental/CodingDetail.h>
#include <folly/experimental/Instructions.h>
#include <folly/experimental/Select64.h>
#include <glog/logging.h>
namespace detail {
template <class Encoder, class Instructions, class SizeType>
-class UpperBitsReader {
+class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
+ SkipPointers<Encoder::skipQuantum> {
typedef typename Encoder::SkipValueType SkipValueType;
public:
typedef typename Encoder::ValueType ValueType;
explicit UpperBitsReader(const typename Encoder::CompressedList& list)
- : forwardPointers_(list.forwardPointers),
- skipPointers_(list.skipPointers),
+ : ForwardPointers<Encoder::forwardQuantum>(list.forwardPointers),
+ SkipPointers<Encoder::skipQuantum>(list.skipPointers),
start_(list.upper) {
reset();
}
// Use forward pointer.
if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) {
const size_t steps = position_ / Encoder::forwardQuantum;
- const size_t dest =
- folly::loadUnaligned<SkipValueType>(
- forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
+ const size_t dest = folly::loadUnaligned<SkipValueType>(
+ this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
reposition(dest + steps * Encoder::forwardQuantum);
n = position_ + 1 - steps * Encoder::forwardQuantum; // n is > 0.
// Use skip pointer.
if (Encoder::skipQuantum > 0 && v >= value_ + Encoder::skipQuantum) {
const size_t steps = v / Encoder::skipQuantum;
- const size_t dest =
- folly::loadUnaligned<SkipValueType>(
- skipPointers_ + (steps - 1) * sizeof(SkipValueType));
+ const size_t dest = folly::loadUnaligned<SkipValueType>(
+ this->skipPointers_ + (steps - 1) * sizeof(SkipValueType));
reposition(dest + Encoder::skipQuantum * steps);
position_ = dest - 1;
// so a type that can hold either sizes or values is sufficient.
using OuterType = typename std::common_type<ValueType, SizeType>::type;
- const unsigned char* const forwardPointers_;
- const unsigned char* const skipPointers_;
const unsigned char* const start_;
block_t block_;
SizeType position_; // Index of current value (= #reads - 1).