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

Store pointers in EliasFanoReader and BitVectorReader only if quantum > 0

Summary:
No need to store the pointers to forward and skip arrays if
they're not used.

Reviewed By: luciang

Differential Revision: D4977014

fbshipit-source-id: 2ed13fdcd1561da1a294f5895f3a5e1b77f1701c
parent 121ecb47
...@@ -107,6 +107,7 @@ nobase_follyinclude_HEADERS = \ ...@@ -107,6 +107,7 @@ nobase_follyinclude_HEADERS = \
experimental/ThreadedRepeatingFunctionRunner.h \ experimental/ThreadedRepeatingFunctionRunner.h \
experimental/Bits.h \ experimental/Bits.h \
experimental/BitVectorCoding.h \ experimental/BitVectorCoding.h \
experimental/CodingDetail.h \
experimental/DynamicParser.h \ experimental/DynamicParser.h \
experimental/DynamicParser-inl.h \ experimental/DynamicParser-inl.h \
experimental/ExecutionObserver.h \ experimental/ExecutionObserver.h \
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/experimental/Bits.h> #include <folly/experimental/Bits.h>
#include <folly/experimental/CodingDetail.h>
#include <folly/experimental/Instructions.h> #include <folly/experimental/Instructions.h>
#include <folly/experimental/Select64.h> #include <folly/experimental/Select64.h>
#include <glog/logging.h> #include <glog/logging.h>
...@@ -233,10 +234,12 @@ struct BitVectorEncoder<Value, SkipValue, kSkipQuantum, kForwardQuantum>:: ...@@ -233,10 +234,12 @@ struct BitVectorEncoder<Value, SkipValue, kSkipQuantum, kForwardQuantum>::
size_t forwardPointers = 0; size_t forwardPointers = 0;
}; };
template <class Encoder, template <
class Encoder,
class Instructions = instructions::Default, class Instructions = instructions::Default,
bool kUnchecked = false> bool kUnchecked = false>
class BitVectorReader { class BitVectorReader : detail::ForwardPointers<Encoder::forwardQuantum>,
detail::SkipPointers<Encoder::skipQuantum> {
public: public:
typedef Encoder EncoderType; typedef Encoder EncoderType;
typedef typename Encoder::ValueType ValueType; typedef typename Encoder::ValueType ValueType;
...@@ -245,10 +248,10 @@ class BitVectorReader { ...@@ -245,10 +248,10 @@ class BitVectorReader {
typedef typename Encoder::SkipValueType SkipValueType; typedef typename Encoder::SkipValueType SkipValueType;
explicit BitVectorReader(const typename Encoder::CompressedList& list) 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), bits_(list.bits),
skipPointers_(list.skipPointers), size_(list.size) {
forwardPointers_(list.forwardPointers) {
reset(); reset();
if (kUnchecked || UNLIKELY(list.size == 0)) { if (kUnchecked || UNLIKELY(list.size == 0)) {
...@@ -303,7 +306,7 @@ class BitVectorReader { ...@@ -303,7 +306,7 @@ class BitVectorReader {
if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) { if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) {
const size_t steps = position_ / Encoder::forwardQuantum; const size_t steps = position_ / Encoder::forwardQuantum;
const size_t dest = folly::loadUnaligned<SkipValueType>( const size_t dest = folly::loadUnaligned<SkipValueType>(
forwardPointers_ + (steps - 1) * sizeof(SkipValueType)); this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
reposition(dest); reposition(dest);
n = position_ + 1 - steps * Encoder::forwardQuantum; n = position_ + 1 - steps * Encoder::forwardQuantum;
...@@ -347,7 +350,7 @@ class BitVectorReader { ...@@ -347,7 +350,7 @@ class BitVectorReader {
if (Encoder::skipQuantum > 0 && v - value_ > Encoder::skipQuantum) { if (Encoder::skipQuantum > 0 && v - value_ > Encoder::skipQuantum) {
size_t q = v / Encoder::skipQuantum; size_t q = v / Encoder::skipQuantum;
auto skipPointer = folly::loadUnaligned<SkipValueType>( auto skipPointer = folly::loadUnaligned<SkipValueType>(
skipPointers_ + (q - 1) * sizeof(SkipValueType)); this->skipPointers_ + (q - 1) * sizeof(SkipValueType));
position_ = static_cast<SizeType>(skipPointer) - 1; position_ = static_cast<SizeType>(skipPointer) - 1;
reposition(q * Encoder::skipQuantum); reposition(q * Encoder::skipQuantum);
...@@ -429,6 +432,7 @@ class BitVectorReader { ...@@ -429,6 +432,7 @@ class BitVectorReader {
constexpr static size_t kLinearScanThreshold = 4; constexpr static size_t kLinearScanThreshold = 4;
const uint8_t* const bits_;
uint64_t block_; uint64_t block_;
SizeType outer_; SizeType outer_;
SizeType position_; SizeType position_;
...@@ -436,9 +440,6 @@ class BitVectorReader { ...@@ -436,9 +440,6 @@ class BitVectorReader {
SizeType size_; SizeType size_;
ValueType upperBound_; ValueType upperBound_;
const uint8_t* const bits_;
const uint8_t* const skipPointers_;
const uint8_t* const forwardPointers_;
}; };
}} // namespaces }} // namespaces
/*
* 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_{};
};
}
}
}
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <folly/Likely.h> #include <folly/Likely.h>
#include <folly/Portability.h> #include <folly/Portability.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/experimental/CodingDetail.h>
#include <folly/experimental/Instructions.h> #include <folly/experimental/Instructions.h>
#include <folly/experimental/Select64.h> #include <folly/experimental/Select64.h>
#include <glog/logging.h> #include <glog/logging.h>
...@@ -332,14 +333,15 @@ struct EliasFanoEncoderV2<Value, ...@@ -332,14 +333,15 @@ struct EliasFanoEncoderV2<Value,
namespace detail { namespace detail {
template <class Encoder, class Instructions, class SizeType> template <class Encoder, class Instructions, class SizeType>
class UpperBitsReader { class UpperBitsReader : ForwardPointers<Encoder::forwardQuantum>,
SkipPointers<Encoder::skipQuantum> {
typedef typename Encoder::SkipValueType SkipValueType; typedef typename Encoder::SkipValueType SkipValueType;
public: public:
typedef typename Encoder::ValueType ValueType; typedef typename Encoder::ValueType ValueType;
explicit UpperBitsReader(const typename Encoder::CompressedList& list) explicit UpperBitsReader(const typename Encoder::CompressedList& list)
: forwardPointers_(list.forwardPointers), : ForwardPointers<Encoder::forwardQuantum>(list.forwardPointers),
skipPointers_(list.skipPointers), SkipPointers<Encoder::skipQuantum>(list.skipPointers),
start_(list.upper) { start_(list.upper) {
reset(); reset();
} }
...@@ -380,9 +382,8 @@ class UpperBitsReader { ...@@ -380,9 +382,8 @@ class UpperBitsReader {
// Use forward pointer. // Use forward pointer.
if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) { if (Encoder::forwardQuantum > 0 && n > Encoder::forwardQuantum) {
const size_t steps = position_ / Encoder::forwardQuantum; const size_t steps = position_ / Encoder::forwardQuantum;
const size_t dest = const size_t dest = folly::loadUnaligned<SkipValueType>(
folly::loadUnaligned<SkipValueType>( this->forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
forwardPointers_ + (steps - 1) * sizeof(SkipValueType));
reposition(dest + steps * Encoder::forwardQuantum); reposition(dest + steps * Encoder::forwardQuantum);
n = position_ + 1 - steps * Encoder::forwardQuantum; // n is > 0. n = position_ + 1 - steps * Encoder::forwardQuantum; // n is > 0.
...@@ -412,9 +413,8 @@ class UpperBitsReader { ...@@ -412,9 +413,8 @@ class UpperBitsReader {
// Use skip pointer. // Use skip pointer.
if (Encoder::skipQuantum > 0 && v >= value_ + Encoder::skipQuantum) { if (Encoder::skipQuantum > 0 && v >= value_ + Encoder::skipQuantum) {
const size_t steps = v / Encoder::skipQuantum; const size_t steps = v / Encoder::skipQuantum;
const size_t dest = const size_t dest = folly::loadUnaligned<SkipValueType>(
folly::loadUnaligned<SkipValueType>( this->skipPointers_ + (steps - 1) * sizeof(SkipValueType));
skipPointers_ + (steps - 1) * sizeof(SkipValueType));
reposition(dest + Encoder::skipQuantum * steps); reposition(dest + Encoder::skipQuantum * steps);
position_ = dest - 1; position_ = dest - 1;
...@@ -507,8 +507,6 @@ class UpperBitsReader { ...@@ -507,8 +507,6 @@ class UpperBitsReader {
// so a type that can hold either sizes or values is sufficient. // so a type that can hold either sizes or values is sufficient.
using OuterType = typename std::common_type<ValueType, SizeType>::type; using OuterType = typename std::common_type<ValueType, SizeType>::type;
const unsigned char* const forwardPointers_;
const unsigned char* const skipPointers_;
const unsigned char* const start_; const unsigned char* const start_;
block_t block_; block_t block_;
SizeType position_; // Index of current value (= #reads - 1). SizeType position_; // Index of current value (= #reads - 1).
......
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