File: C:/Users/fred/anaconda3/Library/include/orc/Vector.hh
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
#ifndef ORC_VECTOR_HH
#define ORC_VECTOR_HH
#include "Int128.hh"
#include "MemoryPool.hh"
#include "orc/orc-config.hh"
#include <cstdlib>
#include <cstring>
#include <list>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <vector>
namespace orc {
/**
* The base class for each of the column vectors. This class handles
* the generic attributes such as number of elements, capacity, and
* notNull vector.
* Note: If hasNull is false, the values in the notNull buffer are not required.
* On the writer side, it does not read values from notNull buffer so users are
* not expected to write notNull buffer if hasNull is false. On the reader side,
* it does not set notNull buffer if hasNull is false, meaning that it is undefined
* behavior to consume values from notNull buffer in this case by downstream users.
*/
struct ColumnVectorBatch {
ColumnVectorBatch(uint64_t capacity, MemoryPool& pool);
virtual ~ColumnVectorBatch();
// the number of slots available
uint64_t capacity;
// the number of current occupied slots
uint64_t numElements;
// an array of capacity length marking non-null values
DataBuffer<char> notNull;
// whether there are any null values
bool hasNulls;
// whether the vector batch is encoded
bool isEncoded;
// custom memory pool
MemoryPool& memoryPool;
/**
* Generate a description of this vector as a string.
*/
virtual std::string toString() const = 0;
/**
* Change the number of slots to at least the given capacity.
* This function is not recursive into subtypes.
*/
virtual void resize(uint64_t capacity);
/**
* Empties the vector from all its elements, recursively.
* Do not alter the current capacity.
*/
virtual void clear();
/**
* Heap memory used by the batch.
*/
virtual uint64_t getMemoryUsage();
/**
* Check whether the batch length varies depending on data.
*/
virtual bool hasVariableLength();
private:
ColumnVectorBatch(const ColumnVectorBatch&);
ColumnVectorBatch& operator=(const ColumnVectorBatch&);
};
template <typename ValueType>
struct IntegerVectorBatch : public ColumnVectorBatch {
IntegerVectorBatch(uint64_t cap, MemoryPool& pool)
: ColumnVectorBatch(cap, pool), data(pool, cap) {
// PASS
}
~IntegerVectorBatch() override = default;
inline std::string toString() const override;
void resize(uint64_t cap) override {
if (capacity < cap) {
ColumnVectorBatch::resize(cap);
data.resize(cap);
}
}
void clear() override {
numElements = 0;
}
uint64_t getMemoryUsage() override {
return ColumnVectorBatch::getMemoryUsage() +
static_cast<uint64_t>(data.capacity() * sizeof(ValueType));
}
DataBuffer<ValueType> data;
};
using LongVectorBatch = IntegerVectorBatch<int64_t>;
using IntVectorBatch = IntegerVectorBatch<int32_t>;
using ShortVectorBatch = IntegerVectorBatch<int16_t>;
using ByteVectorBatch = IntegerVectorBatch<int8_t>;
template <>
inline std::string LongVectorBatch::toString() const {
std::ostringstream buffer;
buffer << "Long vector <" << numElements << " of " << capacity << ">";
return buffer.str();
}
template <>
inline std::string IntVectorBatch::toString() const {
std::ostringstream buffer;
buffer << "Int vector <" << numElements << " of " << capacity << ">";
return buffer.str();
}
template <>
inline std::string ShortVectorBatch::toString() const {
std::ostringstream buffer;
buffer << "Short vector <" << numElements << " of " << capacity << ">";
return buffer.str();
}
template <>
inline std::string ByteVectorBatch::toString() const {
std::ostringstream buffer;
buffer << "Byte vector <" << numElements << " of " << capacity << ">";
return buffer.str();
}
template <typename FloatType>
struct FloatingVectorBatch : public ColumnVectorBatch {
FloatingVectorBatch(uint64_t cap, MemoryPool& pool)
: ColumnVectorBatch(cap, pool), data(pool, cap) {
// PASS
}
~FloatingVectorBatch() override = default;
inline std::string toString() const override;
void resize(uint64_t cap) override {
if (capacity < cap) {
ColumnVectorBatch::resize(cap);
data.resize(cap);
}
}
void clear() override {
numElements = 0;
}
uint64_t getMemoryUsage() override {
return ColumnVectorBatch::getMemoryUsage() +
static_cast<uint64_t>(data.capacity() * sizeof(FloatType));
}
DataBuffer<FloatType> data;
};
using DoubleVectorBatch = FloatingVectorBatch<double>;
using FloatVectorBatch = FloatingVectorBatch<float>;
template <>
inline std::string DoubleVectorBatch::toString() const {
std::ostringstream buffer;
buffer << "Double vector <" << numElements << " of " << capacity << ">";
return buffer.str();
}
template <>
inline std::string FloatVectorBatch::toString() const {
std::ostringstream buffer;
buffer << "Float vector <" << numElements << " of " << capacity << ">";
return buffer.str();
}
struct StringVectorBatch : public ColumnVectorBatch {
StringVectorBatch(uint64_t capacity, MemoryPool& pool);
~StringVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
// pointers to the start of each string
DataBuffer<char*> data;
// the length of each string
DataBuffer<int64_t> length;
// string blob
DataBuffer<char> blob;
};
struct StringDictionary {
StringDictionary(MemoryPool& pool);
DataBuffer<char> dictionaryBlob;
// Offset for each dictionary key entry.
DataBuffer<int64_t> dictionaryOffset;
void getValueByIndex(int64_t index, char*& valPtr, int64_t& length) {
if (index < 0 || static_cast<uint64_t>(index) + 1 >= dictionaryOffset.size()) {
throw std::out_of_range("index out of range.");
}
int64_t* offsetPtr = dictionaryOffset.data();
valPtr = dictionaryBlob.data() + offsetPtr[index];
length = offsetPtr[index + 1] - offsetPtr[index];
}
};
/**
* Include a index array with reference to corresponding dictionary.
* User first obtain index from index array and retrieve string pointer
* and length by calling getValueByIndex() from dictionary.
*/
struct EncodedStringVectorBatch : public StringVectorBatch {
EncodedStringVectorBatch(uint64_t capacity, MemoryPool& pool);
~EncodedStringVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
std::shared_ptr<StringDictionary> dictionary;
// index for dictionary entry
DataBuffer<int64_t> index;
};
struct StructVectorBatch : public ColumnVectorBatch {
StructVectorBatch(uint64_t capacity, MemoryPool& pool);
~StructVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
bool hasVariableLength() override;
std::vector<ColumnVectorBatch*> fields;
};
struct ListVectorBatch : public ColumnVectorBatch {
ListVectorBatch(uint64_t capacity, MemoryPool& pool);
~ListVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
bool hasVariableLength() override;
/**
* The offset of the first element of each list.
* The length of list i is offsets[i+1] - offsets[i].
*/
DataBuffer<int64_t> offsets;
// the concatenated elements
std::unique_ptr<ColumnVectorBatch> elements;
};
struct MapVectorBatch : public ColumnVectorBatch {
MapVectorBatch(uint64_t capacity, MemoryPool& pool);
~MapVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
bool hasVariableLength() override;
/**
* The offset of the first element of each map.
* The size of map i is offsets[i+1] - offsets[i].
*/
DataBuffer<int64_t> offsets;
// the concatenated keys
std::unique_ptr<ColumnVectorBatch> keys;
// the concatenated elements
std::unique_ptr<ColumnVectorBatch> elements;
};
struct UnionVectorBatch : public ColumnVectorBatch {
UnionVectorBatch(uint64_t capacity, MemoryPool& pool);
~UnionVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
bool hasVariableLength() override;
/**
* For each value, which element of children has the value.
*/
DataBuffer<unsigned char> tags;
/**
* For each value, the index inside of the child ColumnVectorBatch.
*/
DataBuffer<uint64_t> offsets;
// the sub-columns
std::vector<ColumnVectorBatch*> children;
};
struct Decimal {
Decimal(const Int128& value, int32_t scale);
explicit Decimal(const std::string& value);
Decimal();
std::string toString(bool trimTrailingZeros = false) const;
Int128 value;
int32_t scale;
};
struct Decimal64VectorBatch : public ColumnVectorBatch {
Decimal64VectorBatch(uint64_t capacity, MemoryPool& pool);
~Decimal64VectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
// total number of digits
int32_t precision;
// the number of places after the decimal
int32_t scale;
// the numeric values
DataBuffer<int64_t> values;
protected:
/**
* Contains the scales that were read from the file. Should NOT be
* used.
*/
DataBuffer<int64_t> readScales;
friend class Decimal64ColumnReader;
friend class Decimal64ColumnWriter;
};
struct Decimal128VectorBatch : public ColumnVectorBatch {
Decimal128VectorBatch(uint64_t capacity, MemoryPool& pool);
~Decimal128VectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
// total number of digits
int32_t precision;
// the number of places after the decimal
int32_t scale;
// the numeric values
DataBuffer<Int128> values;
protected:
/**
* Contains the scales that were read from the file. Should NOT be
* used.
*/
DataBuffer<int64_t> readScales;
friend class Decimal128ColumnReader;
friend class DecimalHive11ColumnReader;
friend class Decimal128ColumnWriter;
};
/**
* A column vector batch for storing timestamp values.
* The timestamps are stored split into the time_t value (seconds since
* 1 Jan 1970 00:00:00) and the nanoseconds within the time_t value.
*/
struct TimestampVectorBatch : public ColumnVectorBatch {
TimestampVectorBatch(uint64_t capacity, MemoryPool& pool);
~TimestampVectorBatch() override;
std::string toString() const override;
void resize(uint64_t capacity) override;
void clear() override;
uint64_t getMemoryUsage() override;
// the number of seconds past 1 Jan 1970 00:00 UTC (aka time_t)
// Note that we always assume data is in GMT timezone; therefore it is
// user's responsibility to convert wall clock time in local timezone
// to GMT.
DataBuffer<int64_t> data;
// the nanoseconds of each value
DataBuffer<int64_t> nanoseconds;
};
} // namespace orc
#endif