1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-06-13 16:01:32 +03:00

This patch introduces support for scanning/filtering vectorized execution for numeric-based

data types TEXT, CHAR, VARCHAR, FLOAT and DOUBLE are not yet supported by vectorized path
This patch introduces an example for Google benchmarking suite to measure a perf diff
b/w legacy scan/filtering code and the templated version
This commit is contained in:
Roman Nozdrin
2021-09-08 17:59:20 +00:00
committed by Roman Nozdrin
parent cac23b0afc
commit af36f9940f
22 changed files with 2720 additions and 143 deletions

View File

@ -185,6 +185,7 @@ IF (NOT INSTALL_LAYOUT)
MY_CHECK_AND_SET_COMPILER_FLAG("-g -O3 -std=c++11 -fno-omit-frame-pointer -fno-strict-aliasing -Wall -fno-tree-vectorize -D_GLIBCXX_ASSERTIONS -DDBUG_OFF -DHAVE_CONFIG_H" RELEASE RELWITHDEBINFO MINSIZEREL) MY_CHECK_AND_SET_COMPILER_FLAG("-g -O3 -std=c++11 -fno-omit-frame-pointer -fno-strict-aliasing -Wall -fno-tree-vectorize -D_GLIBCXX_ASSERTIONS -DDBUG_OFF -DHAVE_CONFIG_H" RELEASE RELWITHDEBINFO MINSIZEREL)
MY_CHECK_AND_SET_COMPILER_FLAG("-ggdb3 -std=c++11 -fno-omit-frame-pointer -fno-tree-vectorize -D_GLIBCXX_ASSERTIONS -DSAFE_MUTEX -DSAFEMALLOC -DENABLED_DEBUG_SYNC -O0 -Wall -D_DEBUG -DHAVE_CONFIG_H" DEBUG) MY_CHECK_AND_SET_COMPILER_FLAG("-ggdb3 -std=c++11 -fno-omit-frame-pointer -fno-tree-vectorize -D_GLIBCXX_ASSERTIONS -DSAFE_MUTEX -DSAFEMALLOC -DENABLED_DEBUG_SYNC -O0 -Wall -D_DEBUG -DHAVE_CONFIG_H" DEBUG)
MY_CHECK_AND_SET_COMPILER_FLAG("-msse4.2" RELEASE RELWITHDEBINFO MINSIZEREL DEBUG)
# enable security hardening features, like most distributions do # enable security hardening features, like most distributions do
# in our benchmarks that costs about ~1% of performance, depending on the load # in our benchmarks that costs about ~1% of performance, depending on the load
@ -212,6 +213,7 @@ ELSE ()
# Remove visibility flag for now as it breaks Ubuntu 18.05 and we need to # Remove visibility flag for now as it breaks Ubuntu 18.05 and we need to
# fix our libraries anyway # fix our libraries anyway
STRING(REPLACE "-fvisibility=hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") STRING(REPLACE "-fvisibility=hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
MY_CHECK_AND_SET_COMPILER_FLAG("-msse4.2" RELEASE RELWITHDEBINFO MINSIZEREL DEBUG)
MY_CHECK_AND_SET_COMPILER_FLAG("-D_DEBUG -O0" DEBUG) MY_CHECK_AND_SET_COMPILER_FLAG("-D_DEBUG -O0" DEBUG)
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG) MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
ENDIF() ENDIF()

View File

@ -826,7 +826,7 @@ namespace primitives
inline primitives::RIDType* getRIDArrayPosition(uint8_t* out, const NVALSType offset) inline primitives::RIDType* getRIDArrayPosition(uint8_t* out, const NVALSType offset)
{ {
return getValuesArrayPosition<NVALSType>(out, offset); return getValuesArrayPosition<RIDType>(out, offset);
} }
inline uint8_t* getFirstValueArrayPosition(ColResultHeader* outMsg) inline uint8_t* getFirstValueArrayPosition(ColResultHeader* outMsg)

View File

@ -21,6 +21,7 @@
//#define NDEBUG //#define NDEBUG
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <functional>
#ifndef _MSC_VER #ifndef _MSC_VER
#include <pthread.h> #include <pthread.h>
#else #else
@ -38,6 +39,8 @@ using namespace boost;
#include "primproc.h" #include "primproc.h"
#include "dataconvert.h" #include "dataconvert.h"
#include "mcs_decimal.h" #include "mcs_decimal.h"
#include "simd_sse.h"
#include "utils/common/columnwidth.h"
using namespace logging; using namespace logging;
using namespace dbbc; using namespace dbbc;
@ -47,7 +50,8 @@ using namespace execplan;
namespace namespace
{ {
using RID_T = uint16_t; // Row index type, as used in rid arrays // WIP Move this
using MT = uint16_t;
// Column filtering is dispatched 4-way based on the column type, // Column filtering is dispatched 4-way based on the column type,
// which defines implementation of comparison operations for the column values // which defines implementation of comparison operations for the column values
@ -118,7 +122,7 @@ inline bool colCompare_(const T& val1, const T& val2, uint8_t COP)
return val1 >= val2; return val1 >= val2;
default: default:
logIt(34, COP, "colCompare"); logIt(34, COP, "colCompare_");
return false; // throw an exception here? return false; // throw an exception here?
} }
} }
@ -848,6 +852,34 @@ inline bool matchingColValue(const T curValue,
} }
} }
/*****************************************************************************
*** MISC FUNCS **************************************************************
*****************************************************************************/
// These two are templates update min/max values in the loop iterating the values in filterColumnData.
template<ENUM_KIND KIND, typename T,
typename std::enable_if<KIND == KIND_TEXT, T>::type* = nullptr>
inline void updateMinMax(T& Min, T& Max, const T curValue, NewColRequestHeader* in)
{
constexpr int COL_WIDTH = sizeof(T);
if (colCompare<KIND_TEXT, COL_WIDTH>(Min, curValue, COMPARE_GT, false, in->colType))
Min = curValue;
if (colCompare<KIND_TEXT, COL_WIDTH>(Max, curValue, COMPARE_LT, false, in->colType))
Max = curValue;
}
template<ENUM_KIND KIND, typename T,
typename std::enable_if<KIND != KIND_TEXT, T>::type* = nullptr>
inline void updateMinMax(T& Min, T& Max, const T curValue, NewColRequestHeader* in)
{
if (Min > curValue)
Min = curValue;
if (Max < curValue)
Max = curValue;
}
/***************************************************************************** /*****************************************************************************
*** READ COLUMN VALUES ****************************************************** *** READ COLUMN VALUES ******************************************************
*****************************************************************************/ *****************************************************************************/
@ -936,6 +968,7 @@ inline void writeColValue(
uint16_t rid, uint16_t rid,
const T* srcArray) const T* srcArray)
{ {
// TODO move base ptr calculation one level up.
uint8_t* outPtr = reinterpret_cast<uint8_t*>(&out[1]); uint8_t* outPtr = reinterpret_cast<uint8_t*>(&out[1]);
auto idx = out->NVALS++; auto idx = out->NVALS++;
if (OutputType & OT_RID) if (OutputType & OT_RID)
@ -947,42 +980,650 @@ inline void writeColValue(
if (OutputType & (OT_TOKEN | OT_DATAVALUE)) if (OutputType & (OT_TOKEN | OT_DATAVALUE))
{ {
// TODO move base ptr calculation one level up.
T* outPos = getValuesArrayPosition<T>(primitives::getFirstValueArrayPosition(out), idx); T* outPos = getValuesArrayPosition<T>(primitives::getFirstValueArrayPosition(out), idx);
// TODO check bytecode for the 16 byte type // TODO check bytecode for the 16 byte type
*outPos = srcArray[rid]; *outPos = srcArray[rid];
} }
} }
// These two are templates update min/max values in the loop iterating the values in filterColumnData. #if defined(__x86_64__ )
template<ENUM_KIND KIND, typename T, template<typename T, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<KIND == KIND_TEXT, T>::type* = nullptr> typename std::enable_if<HAS_INPUT_RIDS == false, T>::type* = nullptr>
inline void updateMinMax(T& Min, T& Max, T& curValue, NewColRequestHeader* in) inline void vectUpdateMinMax(const bool validMinMax, const bool isNonNullOrEmpty,
T& Min, T& Max, T curValue, NewColRequestHeader* in)
{ {
constexpr int COL_WIDTH = sizeof(T); if (validMinMax && isNonNullOrEmpty)
if (colCompare<KIND_TEXT, COL_WIDTH>(Min, curValue, COMPARE_GT, false, in->colType)) updateMinMax<KIND>(Min, Max, curValue, in);
Min = curValue;
if (colCompare<KIND_TEXT, COL_WIDTH>(Max, curValue, COMPARE_LT, false, in->colType))
Max = curValue;
} }
template<ENUM_KIND KIND, typename T, // MCS won't update Min/Max for a block if it doesn't read all values in a block.
typename std::enable_if<KIND != KIND_TEXT, T>::type* = nullptr> // This happens if in->NVALS > 0(HAS_INPUT_RIDS is set).
inline void updateMinMax(T& Min, T& Max, T& curValue, NewColRequestHeader* in) template<typename T, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<HAS_INPUT_RIDS == true, T>::type* = nullptr>
inline void vectUpdateMinMax(const bool validMinMax, const bool isNonNullOrEmpty,
T& Min, T& Max, T curValue, NewColRequestHeader* in)
{ {
if (Min > curValue) //
Min = curValue;
if (Max < curValue)
Max = curValue;
} }
// TBD Check if MCS really needs to copy values from in into out msgs or template<typename T, bool HAS_INPUT_RIDS,
// it is possible to copy from in msg into BPP::values directly. typename std::enable_if<HAS_INPUT_RIDS == false, T>::type* = nullptr>
void vectWriteColValuesLoopRIDAsignment(primitives::RIDType* ridDstArray, ColResultHeader* out,
const primitives::RIDType calculatedRID,
const primitives::RIDType* ridSrcArray, const uint32_t srcRIDIdx)
{
*ridDstArray = calculatedRID;
out->RidFlags |= (1 << (calculatedRID >> 9)); // set the (row/512)'th bit
}
template<typename T, bool HAS_INPUT_RIDS,
typename std::enable_if<HAS_INPUT_RIDS == true, T>::type* = nullptr>
void vectWriteColValuesLoopRIDAsignment(primitives::RIDType* ridDstArray, ColResultHeader* out,
const primitives::RIDType calculatedRID,
const primitives::RIDType* ridSrcArray, const uint32_t srcRIDIdx)
{
*ridDstArray = ridSrcArray[srcRIDIdx];
out->RidFlags |= (1 << (ridSrcArray[srcRIDIdx] >> 9)); // set the (row/512)'th bit
}
// The set of SFINAE templates are used to write values/RID into the output buffer based on
// a number of template parameters
// No RIDs only values
template<typename T, typename VT, int OUTPUT_TYPE, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<OUTPUT_TYPE & (OT_TOKEN | OT_DATAVALUE) && !(OUTPUT_TYPE & OT_RID), T>::type* = nullptr>
inline uint16_t vectWriteColValues(VT& simdProcessor, // SIMD processor
const MT writeMask, // SIMD intrinsics bitmask for values to write
const MT nonNullOrEmptyMask, // SIMD intrinsics inverce bitmask for NULL/EMPTY values
const bool validMinMax, // The flag to update Min/Max for a block or not
const primitives::RIDType ridOffset, // The first RID value of the dataVecTPtr
T* dataVecTPtr, // Typed SIMD vector from the input block
char* dstArray, // the actual char dst array ptr to start writing values
T& Min, T&Max, // Min/Max of the extent
NewColRequestHeader* in, // Proto message
ColResultHeader* out, // Proto message
primitives::RIDType* ridDstArray, // The actual dst arrray ptr to start writing RIDs
primitives::RIDType* ridSrcArray) // The actual src array ptr to read RIDs
{
constexpr const uint16_t WIDTH = sizeof(T);
using SIMD_TYPE = typename VT::SIMD_TYPE;
SIMD_TYPE tmpStorageVector;
T* tmpDstVecTPtr = reinterpret_cast<T*>(&tmpStorageVector);
// Saving values based on writeMask into tmp vec.
// Min/Max processing.
// The mask is 16 bit long and it describes N elements.
// N = sizeof(vector type) / WIDTH.
uint32_t j = 0;
for (uint32_t it = 0; it < VT::vecByteSize; ++j, it += WIDTH)
{
MT bitMapPosition = 1 << it;
if (writeMask & bitMapPosition)
{
*tmpDstVecTPtr = dataVecTPtr[j];
++tmpDstVecTPtr;
}
vectUpdateMinMax<T, KIND, HAS_INPUT_RIDS>(validMinMax, nonNullOrEmptyMask & bitMapPosition,
Min, Max, dataVecTPtr[j], in);
}
// Store the whole vector however one level up the stack
// vectorizedFiltering() increases the dstArray by a number of
// actual values written that is the result of this function.
simdProcessor.store(dstArray, tmpStorageVector);
return tmpDstVecTPtr - reinterpret_cast<T*>(&tmpStorageVector);
}
// RIDs no values
template<typename T, typename VT, int OUTPUT_TYPE, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<OUTPUT_TYPE & OT_RID && !(OUTPUT_TYPE & OT_TOKEN), T>::type* = nullptr>
inline uint16_t vectWriteColValues(VT& simdProcessor, // SIMD processor
const MT writeMask, // SIMD intrinsics bitmask for values to write
const MT nonNullOrEmptyMask, // SIMD intrinsics inverce bitmask for NULL/EMPTY values
const bool validMinMax, // The flag to update Min/Max for a block or not
const primitives::RIDType ridOffset, // The first RID value of the dataVecTPtr
T* dataVecTPtr, // Typed SIMD vector from the input block
char* dstArray, // the actual char dst array ptr to start writing values
T& Min, T&Max, // Min/Max of the extent
NewColRequestHeader* in, // Proto message
ColResultHeader* out, // Proto message
primitives::RIDType* ridDstArray, // The actual dst arrray ptr to start writing RIDs
primitives::RIDType* ridSrcArray) // The actual src array ptr to read RIDs
{
return 0;
}
// Both RIDs and values
template<typename T, typename VT, int OUTPUT_TYPE, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<OUTPUT_TYPE == OT_BOTH, T>::type* = nullptr>
inline uint16_t vectWriteColValues(VT& simdProcessor, // SIMD processor
const MT writeMask, // SIMD intrinsics bitmask for values to write
const MT nonNullOrEmptyMask, // SIMD intrinsics inverce bitmask for NULL/EMPTY values
const bool validMinMax, // The flag to update Min/Max for a block or not
const primitives::RIDType ridOffset, // The first RID value of the dataVecTPtr
T* dataVecTPtr, // Typed SIMD vector from the input block
char* dstArray, // the actual char dst array ptr to start writing values
T& Min, T&Max, // Min/Max of the extent
NewColRequestHeader* in, // Proto message
ColResultHeader* out, // Proto message
primitives::RIDType* ridDstArray, // The actual dst arrray ptr to start writing RIDs
primitives::RIDType* ridSrcArray) // The actual src array ptr to read RIDs
{
constexpr const uint16_t WIDTH = sizeof(T);
using SIMD_TYPE = typename VT::SIMD_TYPE;
SIMD_TYPE tmpStorageVector;
T* tmpDstVecTPtr = reinterpret_cast<T*>(&tmpStorageVector);
// Saving values based on writeMask into tmp vec.
// Min/Max processing.
// The mask is 16 bit long and it describes N elements.
// N = sizeof(vector type) / WIDTH.
uint32_t j = 0;
for (uint32_t it = 0; it < VT::vecByteSize; ++j, it += WIDTH)
{
MT bitMapPosition = 1 << it;
if (writeMask & bitMapPosition)
{
*tmpDstVecTPtr = dataVecTPtr[j];
++tmpDstVecTPtr;
vectWriteColValuesLoopRIDAsignment<T, HAS_INPUT_RIDS>(ridDstArray, out, ridOffset + j,
ridSrcArray, j);
++ridDstArray;
}
vectUpdateMinMax<T, KIND, HAS_INPUT_RIDS>(validMinMax, nonNullOrEmptyMask & bitMapPosition,
Min, Max, dataVecTPtr[j], in);
}
// Store the whole vector however one level up the stack
// vectorizedFiltering() increases the dstArray by a number of
// actual values written that is the result of this function.
simdProcessor.store(dstArray, tmpStorageVector);
return tmpDstVecTPtr - reinterpret_cast<T*>(&tmpStorageVector);
}
// RIDs no values
template<typename T, typename VT, int OUTPUT_TYPE, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<!(OUTPUT_TYPE & (OT_TOKEN | OT_DATAVALUE)) && OUTPUT_TYPE & OT_RID, T>::type* = nullptr>
inline uint16_t vectWriteRIDValues(VT& processor, // SIMD processor
const uint16_t valuesWritten, // The number of values written to in certain SFINAE cases
const bool validMinMax, // The flag to update Min/Max for a block or not
const primitives::RIDType ridOffset, // The first RID value of the dataVecTPtr
T* dataVecTPtr, // Typed SIMD vector from the input block
primitives::RIDType* ridDstArray, // The actual dst arrray ptr to start writing RIDs
MT writeMask, // SIMD intrinsics bitmask for values to write
T& Min, T&Max, // Min/Max of the extent
NewColRequestHeader* in, // Proto message
ColResultHeader* out, // Proto message
MT nonNullOrEmptyMask, // SIMD intrinsics inverce bitmask for NULL/EMPTY values
primitives::RIDType* ridSrcArray) // The actual src array ptr to read RIDs
{
constexpr const uint16_t WIDTH = sizeof(T);
primitives::RIDType* origRIDDstArray = ridDstArray;
// Saving values based on writeMask into tmp vec.
// Min/Max processing.
// The mask is 16 bit long and it describes N elements where N = sizeof(vector type) / WIDTH.
uint16_t j = 0;
for (uint32_t it = 0; it < VT::vecByteSize; ++j, it += WIDTH)
{
MT bitMapPosition = 1 << it;
if (writeMask & (1 << it))
{
vectWriteColValuesLoopRIDAsignment<T, HAS_INPUT_RIDS>(ridDstArray, out, ridOffset + j,
ridSrcArray, j);
++ridDstArray;
}
vectUpdateMinMax<T, KIND, HAS_INPUT_RIDS>(validMinMax, nonNullOrEmptyMask & bitMapPosition,
Min, Max, dataVecTPtr[j], in);
}
return ridDstArray - origRIDDstArray;
}
// Both RIDs and values
// vectWriteColValues writes RIDs traversing the writeMask.
template<typename T, typename VT, int OUTPUT_TYPE, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<OUTPUT_TYPE == OT_BOTH, T>::type* = nullptr>
inline uint16_t vectWriteRIDValues(VT& processor, // SIMD processor
const uint16_t valuesWritten, // The number of values written to in certain SFINAE cases
const bool validMinMax, // The flag to update Min/Max for a block or not
const primitives::RIDType ridOffset, // The first RID value of the dataVecTPtr
T* dataVecTPtr, // Typed SIMD vector from the input block
primitives::RIDType* ridDstArray, // The actual dst arrray ptr to start writing RIDs
MT writeMask, // SIMD intrinsics bitmask for values to write
T& Min, T&Max, // Min/Max of the extent
NewColRequestHeader* in, // Proto message
ColResultHeader* out, // Proto message
MT nonNullOrEmptyMask, // SIMD intrinsics inverce bitmask for NULL/EMPTY values
primitives::RIDType* ridSrcArray) // The actual src array ptr to read RIDs
{
return valuesWritten;
}
// No RIDs only values
template<typename T, typename VT, int OUTPUT_TYPE, ENUM_KIND KIND, bool HAS_INPUT_RIDS,
typename std::enable_if<OUTPUT_TYPE & (OT_TOKEN | OT_DATAVALUE) && !(OUTPUT_TYPE & OT_RID), T>::type* = nullptr>
inline uint16_t vectWriteRIDValues(VT& processor, // SIMD processor
const uint16_t valuesWritten, // The number of values written to in certain SFINAE cases
const bool validMinMax, // The flag to update Min/Max for a block or not
const primitives::RIDType ridOffset, // The first RID value of the dataVecTPtr
T* dataVecTPtr, // Typed SIMD vector from the input block
primitives::RIDType* ridDstArray, // The actual dst arrray ptr to start writing RIDs
MT writeMask, // SIMD intrinsics bitmask for values to write
T& Min, T&Max, // Min/Max of the extent
NewColRequestHeader* in, // Proto message
ColResultHeader* out, // Proto message
MT nonNullOrEmptyMask, // SIMD intrinsics inverce bitmask for NULL/EMPTY values
primitives::RIDType* ridSrcArray) // The actual src array ptr to read RIDs
{
return valuesWritten;
}
#endif
/*****************************************************************************
*** RUN DATA THROUGH A COLUMN FILTER ****************************************
*****************************************************************************/
// TODO turn columnFilterMode into template param to use it in matchingColValue
// This routine filters values in a columnar block processing one scalar at a time.
template<typename T, typename FT, typename ST, ENUM_KIND KIND>
void scalarFiltering(NewColRequestHeader* in, ColResultHeader* out,
const ColumnFilterMode columnFilterMode,
const ST* filterSet, // Set of values for simple filters (any of values / none of them)
const uint32_t filterCount, // Number of filter elements, each described by one entry in the following arrays:
const uint8_t* filterCOPs, // comparison operation
const FT* filterValues, // value to compare to
const uint8_t* filterRFs,
const ColRequestHeaderDataType& typeHolder, // TypeHolder to use collation-aware ops for char/text.
const T* srcArray, // Input array
const uint32_t srcSize, // ... and its size
const uint16_t* ridArray, // Optional array of indexes into srcArray, that defines the read order
const uint16_t ridSize, // ... and its size
const uint32_t initialRID, // The input block idx to start scanning/filter at.
const uint8_t outputType, // Used to decide whether to skip EMPTY values
const bool validMinMax, // The flag to store min/max
T emptyValue, // Deduced empty value magic
T nullValue, // Deduced null value magic
T Min,
T Max,
const bool isNullValueMatches)
{
constexpr int WIDTH = sizeof(T);
// Loop-local variables
T curValue = 0;
primitives::RIDType rid = 0;
bool isEmpty = false;
// Loop over the column values, storing those matching the filter, and updating the min..max range
for (uint32_t i = initialRID;
nextColValue<T, WIDTH>(curValue, &isEmpty,
&i, &rid,
srcArray, srcSize, ridArray, ridSize,
outputType, emptyValue); )
{
if (isEmpty)
continue;
else if (isNullValue<KIND,T>(curValue, nullValue))
{
// If NULL values match the filter, write curValue to the output buffer
if (isNullValueMatches)
writeColValue<T>(outputType, out, rid, srcArray);
}
else
{
// If curValue matches the filter, write it to the output buffer
if (matchingColValue<KIND, WIDTH, false>(curValue, columnFilterMode, filterSet, filterCount,
filterCOPs, filterValues, filterRFs, in->colType, nullValue))
{
writeColValue<T>(outputType, out, rid, srcArray);
}
// Update Min and Max if necessary. EMPTY/NULL values are processed in other branches.
if (validMinMax)
updateMinMax<KIND>(Min, Max, curValue, in);
}
}
// Write captured Min/Max values to *out
out->ValidMinMax = validMinMax;
if (validMinMax)
{
out->Min = Min;
out->Max = Max;
}
}
#if defined(__x86_64__ )
template <typename VT, typename SIMD_WRAPPER_TYPE, bool HAS_INPUT_RIDS, typename T,
typename std::enable_if<HAS_INPUT_RIDS == false, T>::type* = nullptr>
inline SIMD_WRAPPER_TYPE simdDataLoadTemplate(VT& processor, const T* srcArray,
const T* origSrcArray, const primitives::RIDType* ridArray, const uint16_t iter)
{
return {processor.loadFrom(reinterpret_cast<const char*>(srcArray))};
}
// Scatter-gather implementation
// TODO Move the logic into simd namespace class methods and use intrinsics
template <typename VT, typename SIMD_WRAPPER_TYPE, bool HAS_INPUT_RIDS, typename T,
typename std::enable_if<HAS_INPUT_RIDS == true, T>::type* = nullptr>
inline SIMD_WRAPPER_TYPE simdDataLoadTemplate(VT& processor, const T* srcArray,
const T* origSrcArray, const primitives::RIDType* ridArray, const uint16_t iter)
{
constexpr const uint16_t WIDTH = sizeof(T);
constexpr const uint16_t VECTOR_SIZE = VT::vecByteSize / WIDTH;
using SIMD_TYPE = typename VT::SIMD_TYPE;
SIMD_TYPE result;
T* resultTypedPtr = reinterpret_cast<T*>(&result);
for (uint32_t i = 0; i < VECTOR_SIZE; ++i)
{
//std::cout << " simdDataLoadTemplate ridArray[ridArrayOffset] " << (int8_t) origSrcArray[ridArray[i]] << " ridArray[i] " << ridArray[i] << "\n";
resultTypedPtr[i] = origSrcArray[ridArray[i]];
}
return {result};
}
// This routine filters input block in a vectorized manner.
// It supports all output types, all input types.
// It doesn't support KIND==TEXT so upper layers filters this KIND out beforehand.
// It doesn't support KIND==FLOAT yet also.
// To reduce branching it first compiles the filter to produce a vector of
// vector processing class methods(actual filters) pointers and a logical function pointer
// to glue the masks produced by actual filters.
// Then it takes a vector of data, run filters and logical function using pointers.
// See the corresponding dispatcher to get more details on vector processing class.
template<typename T, typename VT, bool HAS_INPUT_RIDS, int OUTPUT_TYPE,
ENUM_KIND KIND, typename FT, typename ST>
void vectorizedFiltering(NewColRequestHeader* in, ColResultHeader* out,
const T* srcArray, const uint32_t srcSize, primitives::RIDType* ridArray,
const uint16_t ridSize, ParsedColumnFilter* parsedColumnFilter,
const bool validMinMax, const T emptyValue, const T nullValue,
T Min, T Max, const bool isNullValueMatches)
{
constexpr const uint16_t WIDTH = sizeof(T);
using SIMD_TYPE = typename VT::SIMD_TYPE;
using SIMD_WRAPPER_TYPE = typename VT::SIMD_WRAPPER_TYPE;
VT simdProcessor;
SIMD_TYPE dataVec;
SIMD_TYPE emptyFilterArgVec = simdProcessor.loadValue(emptyValue);
SIMD_TYPE nullFilterArgVec = simdProcessor.loadValue(nullValue);
MT writeMask, nonEmptyMask, nonNullMask, nonNullOrEmptyMask;
MT initFilterMask = 0xFFFF;
primitives::RIDType rid = 0;
primitives::RIDType* origRidArray = ridArray;
uint16_t totalValuesWritten = 0;
char* dstArray = reinterpret_cast<char*>(primitives::getFirstValueArrayPosition(out));
primitives::RIDType* ridDstArray = reinterpret_cast<primitives::RIDType*>(getFirstRIDArrayPosition(out));
const T* origSrcArray = srcArray;
const FT* filterValues = nullptr;
const ParsedColumnFilter::CopsType* filterCOPs = nullptr;
ColumnFilterMode columnFilterMode = ALWAYS_TRUE;
const ST* filterSet = nullptr;
const ParsedColumnFilter::RFsType* filterRFs = nullptr;
uint8_t outputType = in->OutputType;
constexpr uint16_t VECTOR_SIZE = VT::vecByteSize / WIDTH;
// If there are RIDs use its number to get a number of vectorized iterations.
uint16_t iterNumber = HAS_INPUT_RIDS ? ridSize / VECTOR_SIZE : srcSize / VECTOR_SIZE;
uint32_t filterCount = 0;
// These pragmas are to silence GCC warnings
// warning: ignoring attributes on template argument
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-attributes"
std::vector<SIMD_TYPE> filterArgsVectors;
auto ptrA = std::mem_fn(&VT::cmpEq);
using COPType = decltype(ptrA);
std::vector<COPType> copFunctorVec;
#pragma GCC diagnostic pop
using BOPType = std::function<MT(MT, MT)>;
BOPType bopFunctor;
// filter comparators and logical function compilation.
if (parsedColumnFilter != nullptr)
{
filterValues = parsedColumnFilter->getFilterVals<FT>();
filterCOPs = parsedColumnFilter->prestored_cops.get();
columnFilterMode = parsedColumnFilter->columnFilterMode;
filterSet = parsedColumnFilter->getFilterSet<ST>();
filterRFs = parsedColumnFilter->prestored_rfs.get();
filterCount = parsedColumnFilter->getFilterCount();
if (iterNumber > 0)
{
copFunctorVec.reserve(filterCount);
switch(parsedColumnFilter->getBOP())
{
case BOP_OR:
bopFunctor = std::bit_or<MT>();
initFilterMask = 0;
break;
case BOP_AND:
bopFunctor = std::bit_and<MT>();
break;
case BOP_XOR:
bopFunctor = std::bit_or<MT>();
initFilterMask = 0;
break;
case BOP_NONE:
// According with the comments in linux-port/primitiveprocessor.h
// there can't be BOP_NONE with filterCount > 0
bopFunctor = std::bit_and<MT>();
break;
default:
idbassert(false);
}
filterArgsVectors.reserve(filterCount);
for (uint32_t j = 0; j < filterCount; ++j)
{
// Preload filter argument values only once.
filterArgsVectors[j] = simdProcessor.loadValue(filterValues[j]);
switch(filterCOPs[j])
{
case(COMPARE_EQ):
copFunctorVec.push_back(std::mem_fn(&VT::cmpEq));
break;
case(COMPARE_GE):
copFunctorVec.push_back(std::mem_fn(&VT::cmpGe));
break;
case(COMPARE_GT):
copFunctorVec.push_back(std::mem_fn(&VT::cmpGt));
break;
case(COMPARE_LE):
copFunctorVec.push_back(std::mem_fn(&VT::cmpLe));
break;
case(COMPARE_LT):
copFunctorVec.push_back(std::mem_fn(&VT::cmpLt));
break;
case(COMPARE_NE):
copFunctorVec.push_back(std::mem_fn(&VT::cmpNe));
break;
case(COMPARE_NIL):
copFunctorVec.push_back(std::mem_fn(&VT::cmpAlwaysFalse));
break;
// There are couple other COP, e.g. COMPARE_NOT however they can't be met here
// b/c MCS 6.x uses COMPARE_NOT for strings with OP_LIKE only. See op2num() for
// details.
default:
idbassert(false);
}
}
}
}
// main loop
// writeMask tells which values must get into the result. Includes values that matches filters. Can have NULLs.
// nonEmptyMask tells which vector coords are not EMPTY magics.
// nonNullMask tells which vector coords are not NULL magics.
for (uint16_t i = 0; i < iterNumber; ++i)
{
primitives::RIDType ridOffset = i * VECTOR_SIZE;
assert(!HAS_INPUT_RIDS || (HAS_INPUT_RIDS && ridSize >= ridOffset));
dataVec = simdDataLoadTemplate<VT, SIMD_WRAPPER_TYPE, HAS_INPUT_RIDS, T>(simdProcessor, srcArray, origSrcArray, ridArray, i).v;
// empty check
nonEmptyMask = simdProcessor.cmpNe(dataVec, emptyFilterArgVec);
writeMask = nonEmptyMask;
// NULL check
nonNullMask = simdProcessor.cmpNe(dataVec, nullFilterArgVec);
// Exclude NULLs from the resulting set if NULL doesn't match the filters.
writeMask = isNullValueMatches ? writeMask : writeMask & nonNullMask;
nonNullOrEmptyMask = nonNullMask & nonEmptyMask;
// filters
MT prevFilterMask = initFilterMask;
// TODO name this mask literal
MT filterMask = 0xFFFF;
for (uint32_t j = 0; j < filterCount; ++j)
{
// filter using compiled filter and preloaded filter argument
filterMask = copFunctorVec[j](simdProcessor, dataVec, filterArgsVectors[j]);
filterMask = bopFunctor(prevFilterMask, filterMask);
prevFilterMask = filterMask;
}
writeMask = writeMask & filterMask;
T* dataVecTPtr = reinterpret_cast<T*>(&dataVec);
// vectWriteColValues iterates over the values in the source vec
// to store values/RIDs into dstArray/ridDstArray.
// It also sets Min/Max values for the block if eligible.
// !!! vectWriteColValues increases ridDstArray internally but it doesn't go
// outside the scope of the memory allocated to out msg.
// vectWriteColValues is empty if outputMode == OT_RID.
uint16_t valuesWritten =
vectWriteColValues<T, VT, OUTPUT_TYPE, KIND, HAS_INPUT_RIDS>(simdProcessor,
writeMask,
nonNullOrEmptyMask,
validMinMax,
ridOffset,
dataVecTPtr,
dstArray,
Min, Max,
in, out, ridDstArray,
ridArray);
// Some outputType modes saves RIDs also. vectWriteRIDValues is empty for
// OT_DATAVALUE, OT_BOTH(vectWriteColValues takes care about RIDs).
valuesWritten =
vectWriteRIDValues<T, VT, OUTPUT_TYPE, KIND, HAS_INPUT_RIDS>(simdProcessor,
valuesWritten,
validMinMax,
ridOffset,
dataVecTPtr,
ridDstArray,
writeMask,
Min, Max,
in, out,
nonNullOrEmptyMask,
ridArray);
// Calculate bytes written
uint16_t bytesWritten = valuesWritten * WIDTH;
totalValuesWritten += valuesWritten;
ridDstArray += valuesWritten;
dstArray += bytesWritten;
rid += VECTOR_SIZE;
srcArray += VECTOR_SIZE;
ridArray += VECTOR_SIZE;
}
// Set the number of output values here b/c tail processing can skip this operation.
out->NVALS = totalValuesWritten;
// Write captured Min/Max values to *out
out->ValidMinMax = validMinMax;
if (validMinMax)
{
out->Min = Min;
out->Max = Max;
}
// process the tail. scalarFiltering changes out contents, e.g. Min/Max, NVALS, RIDs and values array
// This tail also sets out::Min/Max, out::validMinMax if validMinMax is set.
uint32_t processedSoFar = rid;
scalarFiltering<T, FT, ST, KIND>(in, out, columnFilterMode, filterSet, filterCount, filterCOPs,
filterValues, filterRFs, in->colType, origSrcArray, srcSize, origRidArray,
ridSize, processedSoFar, outputType, validMinMax, emptyValue, nullValue,
Min, Max, isNullValueMatches);
}
// This routine dispatches template function calls to reduce branching.
template<typename T, ENUM_KIND KIND, typename FT, typename ST>
void vectorizedFilteringDispatcher(NewColRequestHeader* in, ColResultHeader* out,
const T* srcArray, const uint32_t srcSize, uint16_t* ridArray,
const uint16_t ridSize, ParsedColumnFilter* parsedColumnFilter,
const bool validMinMax, const T emptyValue, const T nullValue,
T Min, T Max, const bool isNullValueMatches)
{
constexpr const uint8_t WIDTH = sizeof(T);
// TODO make a SFINAE template switch for the class template spec.
using SIMD_TYPE = simd::vi128_wr;
using VT = typename simd::SimdFilterProcessor<SIMD_TYPE, WIDTH>;
bool hasInputRIDs = (in->NVALS > 0) ? true : false;
if (hasInputRIDs)
{
constexpr const bool hasInput = true;
switch (in->OutputType)
{
case OT_RID:
vectorizedFiltering<T, VT, hasInput, OT_RID, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
case OT_BOTH:
vectorizedFiltering<T, VT, hasInput, OT_BOTH, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
case OT_TOKEN:
vectorizedFiltering<T, VT, hasInput, OT_TOKEN, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
case OT_DATAVALUE:
vectorizedFiltering<T, VT, hasInput, OT_DATAVALUE, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
}
}
else
{
constexpr const bool hasNoInput = false;
switch (in->OutputType)
{
case OT_RID:
vectorizedFiltering<T, VT, hasNoInput, OT_RID, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
case OT_BOTH:
vectorizedFiltering<T, VT, hasNoInput, OT_BOTH, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
case OT_TOKEN:
vectorizedFiltering<T, VT, hasNoInput, OT_TOKEN, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
case OT_DATAVALUE:
vectorizedFiltering<T, VT, hasNoInput, OT_DATAVALUE, KIND, FT, ST>(in, out,
srcArray, srcSize, ridArray, ridSize,
parsedColumnFilter,
validMinMax, emptyValue, nullValue, Min, Max, isNullValueMatches);
break;
}
}
}
#endif
// TBD Make changes in Command class ancestors to threat BPP::values as buffer.
// TBD this will allow to copy values only once from BPP::blockData to the destination.
// This template contains the main scanning/filtering loop. // This template contains the main scanning/filtering loop.
// Copy data matching parsedColumnFilter from input to output. // Copy data matching parsedColumnFilter from input to output.
// Input is srcArray[srcSize], optionally accessed in the order defined by ridArray[ridSize]. // Input is srcArray[srcSize], optionally accessed in the order defined by ridArray[ridSize].
// Output is BLOB out[outSize], written starting at offset *written, which is updated afterward. // Output is buf: ColResponseHeader, RIDType[BLOCK_SIZE], T[BLOCK_SIZE].
template<typename T, ENUM_KIND KIND> template<typename T, ENUM_KIND KIND>
void filterColumnData( void filterColumnData(
NewColRequestHeader* in, NewColRequestHeader* in,
@ -995,7 +1636,7 @@ void filterColumnData(
{ {
using FT = typename IntegralTypeToFilterType<T>::type; using FT = typename IntegralTypeToFilterType<T>::type;
using ST = typename IntegralTypeToFilterSetType<T>::type; using ST = typename IntegralTypeToFilterSetType<T>::type;
constexpr int COL_WIDTH = sizeof(T); constexpr int WIDTH = sizeof(T);
const T* srcArray = reinterpret_cast<const T*>(srcArray16); const T* srcArray = reinterpret_cast<const T*>(srcArray16);
// Cache some structure fields in local vars // Cache some structure fields in local vars
@ -1015,90 +1656,49 @@ void filterColumnData(
auto filterRFs = filterCount==0 ? nullptr : parsedColumnFilter->prestored_rfs.get(); auto filterRFs = filterCount==0 ? nullptr : parsedColumnFilter->prestored_rfs.get();
ST* filterSet = filterCount==0 ? nullptr : parsedColumnFilter->getFilterSet<ST>(); ST* filterSet = filterCount==0 ? nullptr : parsedColumnFilter->getFilterSet<ST>();
// ###########################
// Bit patterns in srcArray[i] representing EMPTY and NULL values // Bit patterns in srcArray[i] representing EMPTY and NULL values
T EMPTY_VALUE = getEmptyValue<T>(dataType); T emptyValue = getEmptyValue<T>(dataType);
T NULL_VALUE = getNullValue<T>(dataType); T nullValue = getNullValue<T>(dataType);
// Precompute filter results for NULL values // Precompute filter results for NULL values
bool isNullValueMatches = matchingColValue<KIND, COL_WIDTH, true>(NULL_VALUE, columnFilterMode, bool isNullValueMatches = matchingColValue<KIND, WIDTH, true>(nullValue, columnFilterMode,
filterSet, filterCount, filterCOPs, filterValues, filterRFs, in->colType, NULL_VALUE); filterSet, filterCount, filterCOPs, filterValues, filterRFs, in->colType, nullValue);
// ###########################
// Boolean indicating whether to capture the min and max values // Boolean indicating whether to capture the min and max values
bool ValidMinMax = isMinMaxValid(in); bool validMinMax = isMinMaxValid(in);
// Local vars to capture the min and max values
T Min = datatypes::numeric_limits<T>::max(); T Min = datatypes::numeric_limits<T>::max();
T Max = (KIND == KIND_UNSIGNED) ? 0 : datatypes::numeric_limits<T>::min(); T Max = (KIND == KIND_UNSIGNED) ? 0 : datatypes::numeric_limits<T>::min();
/* WIP add vertical processing // Vectorized scanning/filtering for all numerics except float/double types.
// If possible, use faster "vertical" filtering approach // If the total number of input values can't fill a vector the vector path
if (KIND != KIND_TEXT) // applies scalar filtering.
// Syscat queries mustn't follow vectorized processing path b/c PP must return
// all values w/o any filter(even empty values filter) applied.
#if defined(__x86_64__ )
// Don't use vectorized filtering for non-integer based data types wider than 16 bytes.
if (KIND < KIND_FLOAT && WIDTH < 16)
{ {
bool canUseFastFiltering = true; bool canUseFastFiltering = true;
for (int i = 0; i < filterCount; ++i) for (uint32_t i = 0; i < filterCount; ++i)
if (filterRFs[i] != 0) if (filterRFs[i] != 0)
canUseFastFiltering = false; canUseFastFiltering = false;
if (canUseFastFiltering) if (canUseFastFiltering)
{ {
processArray<T, KIND, T>(srcArray, srcSize, ridArray, ridSize, vectorizedFilteringDispatcher<T, KIND, FT, ST>(in, out, srcArray, srcSize, ridArray, ridSize,
in->BOP, filterSet, filterCount, filterCOPs, filterValues, parsedColumnFilter.get(), validMinMax, emptyValue,
reinterpret_cast<uint8_t*>(out) + *written, nullValue, Min, Max, isNullValueMatches);
written, & out->NVALS, & out->RidFlags,
(outputType & OT_RID) != 0,
(outputType & (OT_TOKEN | OT_DATAVALUE)) != 0,
(outputType & OT_RID) != 0, //TODO: check correctness of this condition for SKIP_EMPTY_VALUES
EMPTY_VALUE,
isNullValueMatches, NULL_VALUE,
ValidMinMax, &Min, &Max);
return; return;
} }
} }
*/ #endif
uint32_t initialRID = 0;
// Loop-local variables scalarFiltering<T, FT, ST, KIND>(in, out, columnFilterMode, filterSet, filterCount, filterCOPs,
T curValue = 0; filterValues, filterRFs, in->colType, srcArray, srcSize, ridArray,
uint16_t rid = 0; ridSize, initialRID, outputType, validMinMax, emptyValue, nullValue,
bool isEmpty = false; Min, Max, isNullValueMatches);
// Loop over the column values, storing those matching the filter, and updating the min..max range
for (uint32_t i = 0;
nextColValue<T, COL_WIDTH>(curValue, &isEmpty,
&i, &rid,
srcArray, srcSize, ridArray, ridSize,
outputType, EMPTY_VALUE); )
{
if (isEmpty)
continue;
else if (isNullValue<KIND,T>(curValue, NULL_VALUE))
{
// If NULL values match the filter, write curValue to the output buffer
if (isNullValueMatches)
writeColValue<T>(outputType, out, rid, srcArray);
}
else
{
// If curValue matches the filter, write it to the output buffer
if (matchingColValue<KIND, COL_WIDTH, false>(curValue, columnFilterMode, filterSet, filterCount,
filterCOPs, filterValues, filterRFs, in->colType, NULL_VALUE))
{
writeColValue<T>(outputType, out, rid, srcArray);
}
// Update Min and Max if necessary. EMPTY/NULL values are processed in other branches.
if (ValidMinMax)
updateMinMax<KIND>(Min, Max, curValue, in);
}
}
// Write captured Min/Max values to *out
out->ValidMinMax = ValidMinMax;
if (ValidMinMax)
{
out->Min = Min;
out->Max = Max;
}
} // end of filterColumnData } // end of filterColumnData
} //namespace anon } //namespace anon

View File

@ -62,8 +62,8 @@ ParsedColumnFilter::ParsedColumnFilter() : columnFilterMode(ALWAYS_TRUE), mFilte
{ {
} }
ParsedColumnFilter::ParsedColumnFilter(const uint32_t aFilterCount) ParsedColumnFilter::ParsedColumnFilter(const uint32_t aFilterCount, const int BOP)
: columnFilterMode(ALWAYS_TRUE), mFilterCount(aFilterCount) : columnFilterMode(ALWAYS_TRUE), mFilterCount(aFilterCount), mBOP(BOP)
{ {
prestored_rfs.reset(new uint8_t[mFilterCount]); prestored_rfs.reset(new uint8_t[mFilterCount]);
prestored_cops.reset(new uint8_t[mFilterCount]); prestored_cops.reset(new uint8_t[mFilterCount]);

View File

@ -165,17 +165,19 @@ struct IntegralTypeToFilterSetType<int128_t>
class ParsedColumnFilter class ParsedColumnFilter
{ {
public: public:
static constexpr uint32_t noSetFilterThreshold = 8; using CopsType = uint8_t;
using RFsType = uint8_t;
static constexpr uint32_t noSetFilterThreshold = 8;
ColumnFilterMode columnFilterMode; ColumnFilterMode columnFilterMode;
boost::shared_array<int64_t> prestored_argVals; boost::shared_array<int64_t> prestored_argVals;
boost::shared_array<int128_t> prestored_argVals128; boost::shared_array<int128_t> prestored_argVals128;
boost::shared_array<uint8_t> prestored_cops; boost::shared_array<CopsType> prestored_cops;
boost::shared_array<uint8_t> prestored_rfs; boost::shared_array<uint8_t> prestored_rfs;
boost::shared_ptr<prestored_set_t> prestored_set; boost::shared_ptr<prestored_set_t> prestored_set;
boost::shared_ptr<prestored_set_t_128> prestored_set_128; boost::shared_ptr<prestored_set_t_128> prestored_set_128;
ParsedColumnFilter(); ParsedColumnFilter();
ParsedColumnFilter(const uint32_t aFilterCount); ParsedColumnFilter(const uint32_t aFilterCount, const int BOP);
~ParsedColumnFilter(); ~ParsedColumnFilter();
template<typename T, template<typename T,
@ -259,8 +261,19 @@ class ParsedColumnFilter
prestored_set->insert(prestored_argVals[argIndex]); prestored_set->insert(prestored_argVals[argIndex]);
} }
inline int getBOP() const
{
return mBOP;
}
inline int getFilterCount() const
{
return mFilterCount;
}
private: private:
uint32_t mFilterCount; uint32_t mFilterCount;
int mBOP;
}; };
//@bug 1828 These need to be public so that column operations can use it for 'like' //@bug 1828 These need to be public so that column operations can use it for 'like'
@ -400,7 +413,6 @@ public:
template<typename T, template<typename T,
typename std::enable_if<sizeof(T) == sizeof(int64_t), T>::type* = nullptr> typename std::enable_if<sizeof(T) == sizeof(int64_t), T>::type* = nullptr>
void scanAndFilterTypeDispatcher(NewColRequestHeader* in, ColResultHeader* out); void scanAndFilterTypeDispatcher(NewColRequestHeader* in, ColResultHeader* out);
template<typename T, template<typename T,
typename std::enable_if<sizeof(T) <= sizeof(int64_t), T>::type* = nullptr> typename std::enable_if<sizeof(T) <= sizeof(int64_t), T>::type* = nullptr>
void _scanAndFilterTypeDispatcher(NewColRequestHeader* in, ColResultHeader* out); void _scanAndFilterTypeDispatcher(NewColRequestHeader* in, ColResultHeader* out);
@ -433,7 +445,7 @@ public:
// void p_ColAggregate(const NewColAggRequestHeader *in, NewColAggResultHeader *out); // void p_ColAggregate(const NewColAggRequestHeader *in, NewColAggResultHeader *out);
void p_Dictionary(const DictInput* in, std::vector<uint8_t>* out, void p_Dictionary(const DictInput* in, std::vector<uint8_t>* out,
bool skipNulls, uint32_t charsetNumber, bool skipNulls, uint32_t charsetNumber,
boost::shared_ptr<DictEqualityFilter> eqFilter, boost::shared_ptr<DictEqualityFilter> eqFilter,
uint8_t eqOp); uint8_t eqOp);
@ -492,7 +504,7 @@ boost::shared_ptr<ParsedColumnFilter> _parseColumnFilter(
// Allocate the compiled filter structure with space for filterCount filters. // Allocate the compiled filter structure with space for filterCount filters.
// No need to init arrays since they will be filled on the fly. // No need to init arrays since they will be filled on the fly.
ret.reset(new ParsedColumnFilter(filterCount)); ret.reset(new ParsedColumnFilter(filterCount, BOP));
ret->allocateSpaceForFilterArgs<T>(); ret->allocateSpaceForFilterArgs<T>();
// Choose initial filter mode based on operation and number of filter elements // Choose initial filter mode based on operation and number of filter elements

View File

@ -168,12 +168,11 @@ void ColumnCommand::_loadData()
_mask = mask; _mask = mask;
// primMsg->RidFlags = 0xffff; // disables selective block loading //primMsg->RidFlags = 0xffff; // disables selective block loading
//cout <<__FILE__ << "::issuePrimitive() o: " << getOID() << " l:" << primMsg->LBID << " ll: " << oidLastLbid << endl; //cerr << "::ColumnCommand::_loadData OID " << getOID() << " l:" << primMsg->LBID << " ll: " << oidLastLbid << " primMsg->RidFlags " << primMsg->RidFlags << endl;
for (i = 0; i < W; ++i, _mask <<= shift) for (i = 0; i < W; ++i, _mask <<= shift)
{ {
if ((!lastBlockReached && _isScan) || (!_isScan && primMsg->RidFlags & _mask)) if ((!lastBlockReached && _isScan) || (!_isScan && primMsg->RidFlags & _mask))
{ {
lbids[blocksToLoad] = primMsg->LBID + i; lbids[blocksToLoad] = primMsg->LBID + i;
@ -397,7 +396,6 @@ void ColumnCommand::_process_OT_BOTH()
{ {
using T = typename datatypes::WidthToSIntegralType<W>::type; using T = typename datatypes::WidthToSIntegralType<W>::type;
bpp->ridCount = outMsg->NVALS; bpp->ridCount = outMsg->NVALS;
bpp->ridCount = outMsg->NVALS;
bpp->ridMap = outMsg->RidFlags; bpp->ridMap = outMsg->RidFlags;
uint8_t* outPtr = reinterpret_cast<uint8_t*>(&outMsg[1]); uint8_t* outPtr = reinterpret_cast<uint8_t*>(&outMsg[1]);
auto* ridPos = primitives::getRIDArrayPosition(outPtr, 0); auto* ridPos = primitives::getRIDArrayPosition(outPtr, 0);

View File

@ -154,7 +154,7 @@ void DictStep::issuePrimitive(bool isFilter)
if (!(primMsg->LBID & 0x8000000000000000LL)) if (!(primMsg->LBID & 0x8000000000000000LL))
{ {
//cout << "DS issuePrimitive lbid: " << (uint64_t)primMsg->LBID << endl; //std::cerr << "DS issuePrimitive lbid: " << (uint64_t)primMsg->LBID << endl;
primitiveprocessor::loadBlock(primMsg->LBID, primitiveprocessor::loadBlock(primMsg->LBID,
bpp->versionInfo, bpp->versionInfo,
bpp->txnID, bpp->txnID,
@ -577,7 +577,7 @@ void DictStep::_projectToRG(RowGroup& rg, uint32_t col)
for (i = curResultCounter; i < tmpResultCounter; i++) for (i = curResultCounter; i < tmpResultCounter; i++)
{ {
rg.getRow(newRidList[i].pos, &r); rg.getRow(newRidList[i].pos, &r);
//cout << "serializing " << tmpStrings[i] << endl; //std::cerr << "serializing " << tmpStrings[i] << endl;
r.setStringField(tmpStrings[i].getConstString(), col); r.setStringField(tmpStrings[i].getConstString(), col);
} }
} }

View File

@ -42,3 +42,13 @@ if (WITH_UNITTESTS)
add_test(NAME columnstore:comparators_tests, COMMAND comparators_tests) add_test(NAME columnstore:comparators_tests, COMMAND comparators_tests)
endif() endif()
# Saving this as the example of the microbench
#if (WITH_MICROBENCHMARKS AND (NOT CMAKE_BUILD_TYPE STREQUAL "debug"))
# find_package(benchmark REQUIRED)
# add_executable(primitives_scan_bench primitives_scan_bench.cpp)
# target_include_directories(primitives_scan_bench PUBLIC ${ENGINE_COMMON_INCLUDES} ${ENGINE_BLOCKCACHE_INCLUDE} ${ENGINE_PRIMPROC_INCLUDE} )
# target_link_libraries(primitives_scan_bench ${ENGINE_LDFLAGS} ${MARIADB_CLIENT_LIBS} ${ENGINE_WRITE_LIBS} ${GTEST_LIBRARIES} processor dbbc benchmark::benchmark)
# install(TARGETS primitives_scan_bench DESTINATION ${ENGINE_BINDIR} COMPONENT columnstore-engine)
#endif()

708
tests/col16block.h Normal file
View File

@ -0,0 +1,708 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef HAVE_COL16BLOCK
#define HAVE_COL16BLOCK
unsigned char ___bin_col16block_cdf[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x26, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x44, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x56, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x57, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x59, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x62, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x68, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x69, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x92, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xab, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xad, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xae, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xba, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xce, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xd4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xd7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xda, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xdd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xde, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xea, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xec, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xed, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xef, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int ___bin_col16block_cdf_len = 8192;
constexpr int __col16block_cdf_umin = 2;
constexpr int __col16block_cdf_umax = 511;
#endif

View File

@ -703,4 +703,6 @@ unsigned char __col1block_cdf[] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}; };
unsigned int __col1block_cdf_len = 8192; unsigned int __col1block_cdf_len = 8192;
constexpr int __col1block_cdf_umin = -126;
constexpr int __col1block_cdf_umax = 127;
#endif #endif

View File

@ -703,4 +703,6 @@ unsigned char __col2block_cdf[] = {
0xfc, 0x0f, 0xfd, 0x0f, 0xfe, 0x0f, 0xff, 0x0f 0xfc, 0x0f, 0xfd, 0x0f, 0xfe, 0x0f, 0xff, 0x0f
}; };
unsigned int __col2block_cdf_len = 8192; unsigned int __col2block_cdf_len = 8192;
constexpr int __col2block_cdf_umin = 0;
constexpr int __col2block_cdf_umax = 4095;
#endif #endif

View File

@ -703,4 +703,6 @@ unsigned char __col4block_cdf[] = {
0xfe, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00 0xfe, 0x07, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00
}; };
unsigned int __col4block_cdf_len = 8192; unsigned int __col4block_cdf_len = 8192;
constexpr int __col4block_cdf_umin = 0;
constexpr int __col4block_cdf_umax = 2047;
#endif #endif

View File

@ -703,4 +703,6 @@ unsigned char ___bin_col8block_cdf[] = {
0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
unsigned int ___bin_col8block_cdf_len = 8192; unsigned int ___bin_col8block_cdf_len = 8192;
constexpr int __col8block_cdf_umin = 0;
constexpr int __col8block_cdf_umax = 1023;
#endif #endif

View File

@ -17,13 +17,17 @@
#include <iostream> #include <iostream>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "utils/common/columnwidth.h"
#include "datatypes/mcs_datatype.h" #include "datatypes/mcs_datatype.h"
#include "datatypes/mcs_int128.h"
#include "stats.h" #include "stats.h"
#include "primitives/linux-port/primitiveprocessor.h" #include "primitives/linux-port/primitiveprocessor.h"
#include "col1block.h" #include "col1block.h"
#include "col2block.h" #include "col2block.h"
#include "col4block.h" #include "col4block.h"
#include "col8block.h" #include "col8block.h"
#include "col16block.h"
#include "col_float_block.h" #include "col_float_block.h"
#include "col_double_block.h" #include "col_double_block.h"
#include "col_neg_float.h" #include "col_neg_float.h"
@ -33,7 +37,7 @@ using namespace primitives;
using namespace datatypes; using namespace datatypes;
using namespace std; using namespace std;
// If a test crashes check if there is a corresponding literal binary array in // If a test crashes check if there is a corresponding literal binary array in
// readBlockFromLiteralArray. // readBlockFromLiteralArray.
class ColumnScanFilterTest : public ::testing::Test class ColumnScanFilterTest : public ::testing::Test
@ -41,8 +45,8 @@ class ColumnScanFilterTest : public ::testing::Test
protected: protected:
PrimitiveProcessor pp; PrimitiveProcessor pp;
uint8_t input[BLOCK_SIZE]; uint8_t input[BLOCK_SIZE];
uint8_t output[4 * BLOCK_SIZE]; alignas(utils::MAXCOLUMNWIDTH) uint8_t output[4 * BLOCK_SIZE];
uint8_t block[BLOCK_SIZE]; alignas(utils::MAXCOLUMNWIDTH) uint8_t block[BLOCK_SIZE];
uint16_t* rids; uint16_t* rids;
uint32_t i; uint32_t i;
NewColRequestHeader* in; NewColRequestHeader* in;
@ -91,7 +95,7 @@ protected:
close(fd); close(fd);
return block; return block;
} }
uint8_t* readBlockFromLiteralArray(const std::string& fileName, uint8_t* block) uint8_t* readBlockFromLiteralArray(const std::string& fileName, uint8_t* block)
{ {
if (fileName == std::string("col1block.cdf")) if (fileName == std::string("col1block.cdf"))
@ -102,6 +106,8 @@ protected:
return &__col4block_cdf[0]; return &__col4block_cdf[0];
else if (fileName == std::string("col8block.cdf")) else if (fileName == std::string("col8block.cdf"))
return &___bin_col8block_cdf[0]; return &___bin_col8block_cdf[0];
else if (fileName == std::string("col16block.cdf"))
return &___bin_col16block_cdf[0];
else if (fileName == std::string("col_float_block.cdf")) else if (fileName == std::string("col_float_block.cdf"))
return &___bin_col_float_block_cdf[0]; return &___bin_col_float_block_cdf[0];
else if (fileName == std::string("col_double_block.cdf")) else if (fileName == std::string("col_double_block.cdf"))
@ -115,7 +121,6 @@ protected:
} }
}; };
TEST_F(ColumnScanFilterTest, ColumnScan1Byte) TEST_F(ColumnScanFilterTest, ColumnScan1Byte)
{ {
constexpr const uint8_t W = 1; constexpr const uint8_t W = 1;
@ -137,7 +142,42 @@ TEST_F(ColumnScanFilterTest, ColumnScan1Byte)
for (i = 0; i < 300; i++) for (i = 0; i < 300; i++)
EXPECT_EQ(results[i],i % 255); EXPECT_EQ(results[i],i % 255);
// Can't check Min/Max for char columns until MCOL-4871
}
TEST_F(ColumnScanFilterTest, ColumnScan1ByteVectorized)
{
constexpr const uint8_t W = 1;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
in->colType = ColRequestHeaderDataType();
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::TINYINT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 0;
in->NVALS = 0;
pp.setBlockPtr((int*) readBlockFromLiteralArray("col1block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
EXPECT_EQ(out->NVALS, 8160);
for (i = 0; i < 128; ++i)
EXPECT_EQ(results[i],i);
for (i = 129; i < 255; ++i)
EXPECT_EQ(results[i],i + 1);
EXPECT_EQ(results[8032], 0x7F);
EXPECT_EQ(results[8033], 0x80);
for (i = 8034; i < 8160; ++i)
EXPECT_EQ(results[i],i % 255 + 1);
EXPECT_EQ(out->Max, __col1block_cdf_umax);
EXPECT_EQ(out->Min, __col1block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan2Bytes) TEST_F(ColumnScanFilterTest, ColumnScan2Bytes)
@ -160,6 +200,9 @@ TEST_F(ColumnScanFilterTest, ColumnScan2Bytes)
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
EXPECT_EQ(results[i], i); EXPECT_EQ(results[i], i);
EXPECT_EQ(out->Max, __col2block_cdf_umax);
EXPECT_EQ(out->Min, __col2block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan4Bytes) TEST_F(ColumnScanFilterTest, ColumnScan4Bytes)
@ -182,6 +225,8 @@ TEST_F(ColumnScanFilterTest, ColumnScan4Bytes)
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
EXPECT_EQ(results[i], (uint32_t) i); EXPECT_EQ(results[i], (uint32_t) i);
EXPECT_EQ(out->Max, __col4block_cdf_umax);
EXPECT_EQ(out->Min, __col4block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan8Bytes) TEST_F(ColumnScanFilterTest, ColumnScan8Bytes)
@ -204,6 +249,40 @@ TEST_F(ColumnScanFilterTest, ColumnScan8Bytes)
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], (uint32_t) i); ASSERT_EQ(results[i], (uint32_t) i);
EXPECT_EQ(out->Max, __col8block_cdf_umax);
EXPECT_EQ(out->Min, __col8block_cdf_umin);
}
TEST_F(ColumnScanFilterTest, ColumnScan2Bytes1EqFilter)
{
constexpr const uint8_t W = 2;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
IntegralType tmp;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::INT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 1;
in->BOP = BOP_AND;
in->NVALS = 0;
tmp = 50;
args->COP = COMPARE_LE;
memcpy(args->val, &tmp, in->colType.DataSize);
args = reinterpret_cast<ColArgs*>(&input[sizeof(NewColRequestHeader) +
sizeof(ColArgs) + in->colType.DataSize]);
pp.setBlockPtr((int*) readBlockFromLiteralArray("col2block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, 51);
for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], i);
EXPECT_EQ(out->Max, __col2block_cdf_umax);
EXPECT_EQ(out->Min, __col2block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan1ByteUsingRID) TEST_F(ColumnScanFilterTest, ColumnScan1ByteUsingRID)
@ -226,11 +305,101 @@ TEST_F(ColumnScanFilterTest, ColumnScan1ByteUsingRID)
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0); results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, 2); ASSERT_EQ(out->NVALS, 2);
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; ++i)
ASSERT_EQ(results[i], rids[i]); ASSERT_EQ(results[i], rids[i]);
} }
TEST_F(ColumnScanFilterTest, ColumnScan4Bytes1Filter) TEST_F(ColumnScanFilterTest, ColumnScan1ByteUsingMultipleRIDs)
{
constexpr const uint8_t W = 1;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
const size_t expectedNVALS = 127;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::INT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 0;
in->NVALS = expectedNVALS;
for (i = 0; i < expectedNVALS; ++i)
rids[i] = i;
rids[0] = 20;
rids[1] = 17;
rids[126] = 8189;
pp.setBlockPtr((int*) readBlockFromLiteralArray("col1block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, expectedNVALS);
for (i = 0; i < expectedNVALS - 1; ++i)
ASSERT_EQ(results[i], rids[i]);
ASSERT_EQ(results[126], 253);
}
TEST_F(ColumnScanFilterTest, ColumnScan4Bytes1EqFilter)
{
constexpr const uint8_t W = 4;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
IntegralType tmp;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::INT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 1;
in->BOP = BOP_AND;
in->NVALS = 0;
tmp = 2040;
args->COP = COMPARE_GE;
memcpy(args->val, &tmp, in->colType.DataSize);
args = reinterpret_cast<ColArgs*>(&input[sizeof(NewColRequestHeader) +
sizeof(ColArgs) + in->colType.DataSize]);
pp.setBlockPtr((int*) readBlockFromLiteralArray("col4block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, 8);
for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], i + 2040);
}
TEST_F(ColumnScanFilterTest, ColumnScan4BytesUsingMultipleRIDs)
{
constexpr const uint8_t W = 4;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
const size_t expectedNVALS = 127;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::INT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 0;
in->NVALS = expectedNVALS;
for (i = 0; i < expectedNVALS; ++i)
rids[i] = i;
rids[0] = 20;
rids[1] = 17;
rids[126] = 1020;
pp.setBlockPtr((int*) readBlockFromLiteralArray("col4block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, expectedNVALS);
for (i = 0; i < expectedNVALS - 1; ++i)
ASSERT_EQ(results[i], rids[i]);
ASSERT_EQ(results[126], 1020);
}
TEST_F(ColumnScanFilterTest, ColumnScan4Bytes2Filters)
{ {
constexpr const uint8_t W = 4; constexpr const uint8_t W = 4;
using IntegralType = datatypes::WidthToSIntegralType<W>::type; using IntegralType = datatypes::WidthToSIntegralType<W>::type;
@ -261,6 +430,72 @@ TEST_F(ColumnScanFilterTest, ColumnScan4Bytes1Filter)
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], 11 + (uint32_t)i); ASSERT_EQ(results[i], 11 + (uint32_t)i);
EXPECT_EQ(out->Max, __col4block_cdf_umax);
EXPECT_EQ(out->Min, __col4block_cdf_umin);
}
TEST_F(ColumnScanFilterTest, ColumnScan8Bytes1EqFilter)
{
constexpr const uint8_t W = 8;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
IntegralType tmp;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::INT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 1;
in->BOP = BOP_AND;
in->NVALS = 0;
tmp = 11;
args->COP = COMPARE_LT;
memcpy(args->val, &tmp, in->colType.DataSize);
args = reinterpret_cast<ColArgs*>(&input[sizeof(NewColRequestHeader) +
sizeof(ColArgs) + in->colType.DataSize]);
pp.setBlockPtr((int*) readBlockFromLiteralArray("col8block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, 11);
for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], i);
EXPECT_EQ(out->Max, __col8block_cdf_umax);
EXPECT_EQ(out->Min, __col8block_cdf_umin);
}
TEST_F(ColumnScanFilterTest, ColumnScan8BytesUsingMultipleRIDs)
{
constexpr const uint8_t W = 8;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
using UT = datatypes::make_unsigned<IntegralType>::type;
UT* results;
const size_t expectedNVALS = 127;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::INT;
in->OutputType = OT_DATAVALUE;
in->NOPS = 0;
in->NVALS = expectedNVALS;
for (i = 0; i < expectedNVALS; ++i)
rids[i] = i;
rids[0] = 20;
rids[1] = 17;
rids[126] = 1020;
pp.setBlockPtr((int*) readBlockFromLiteralArray("col8block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<UT>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, expectedNVALS);
for (i = 0; i < expectedNVALS - 1; ++i)
ASSERT_EQ(results[i], rids[i]);
ASSERT_EQ(results[126], 1020);
} }
//void p_Col_7() //void p_Col_7()
@ -296,6 +531,9 @@ TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2CompFilters)
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], (uint32_t) (i < 10 ? i : i - 10 + 1001)); ASSERT_EQ(results[i], (uint32_t) (i < 10 ? i : i - 10 + 1001));
EXPECT_EQ(out->Max, __col8block_cdf_umax);
EXPECT_EQ(out->Min, __col8block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFilters) TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFilters)
@ -330,6 +568,8 @@ TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFilters)
ASSERT_EQ(out->NVALS, 2); ASSERT_EQ(out->NVALS, 2);
ASSERT_EQ(results[0], 10); ASSERT_EQ(results[0], 10);
ASSERT_EQ(results[1], 1000); ASSERT_EQ(results[1], 1000);
ASSERT_EQ(out->Max, __col8block_cdf_umax);
ASSERT_EQ(out->Min, __col8block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRID) TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRID)
@ -370,7 +610,7 @@ TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRID)
ASSERT_EQ(results[0], 10); ASSERT_EQ(results[0], 10);
} }
TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRIDOutputRid) TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2FiltersRIDOutputRid)
{ {
constexpr const uint8_t W = 8; constexpr const uint8_t W = 8;
using IntegralType = datatypes::WidthToSIntegralType<W>::type; using IntegralType = datatypes::WidthToSIntegralType<W>::type;
@ -400,7 +640,9 @@ TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRIDOutputRid)
ASSERT_EQ(out->NVALS, 33); ASSERT_EQ(out->NVALS, 33);
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
ASSERT_EQ(results[i], (i < 10 ? i : i - 10 + 1001)); ASSERT_EQ(results[i], (i < 10 ? i : i - 10 + 1001));
ASSERT_EQ(out->Max, __col8block_cdf_umax);
ASSERT_EQ(out->Min, __col8block_cdf_umin);
} }
TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRIDOutputBoth) TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRIDOutputBoth)
@ -437,6 +679,8 @@ TEST_F(ColumnScanFilterTest, ColumnScan8Bytes2EqFiltersRIDOutputBoth)
ASSERT_EQ(resultRid[i], (i < 10 ? i : i - 10 + 1001)); ASSERT_EQ(resultRid[i], (i < 10 ? i : i - 10 + 1001));
ASSERT_EQ(resultVal[i], (i < 10 ? i : i - 10 + 1001)); ASSERT_EQ(resultVal[i], (i < 10 ? i : i - 10 + 1001));
} }
ASSERT_EQ(out->Max, __col8block_cdf_umax);
ASSERT_EQ(out->Min, __col8block_cdf_umin);
} }
//void p_Col_12() //void p_Col_12()
@ -649,7 +893,7 @@ TEST_F(ColumnScanFilterTest, ColumnScan4BytesNegDouble2CompFilters)
pp.setBlockPtr((int*) readBlockFromLiteralArray("col_neg_double.cdf", block)); pp.setBlockPtr((int*) readBlockFromLiteralArray("col_neg_double.cdf", block));
pp.columnScanAndFilter<int64_t>(in, out); pp.columnScanAndFilter<int64_t>(in, out);
//ASSERT_EQ(out->NVALS, 19); ASSERT_EQ(out->NVALS, 19);
for (i = 0; i < out->NVALS; i++) for (i = 0; i < out->NVALS; i++)
{ {
@ -657,8 +901,67 @@ TEST_F(ColumnScanFilterTest, ColumnScan4BytesNegDouble2CompFilters)
} }
} }
TEST_F(ColumnScanFilterTest, ColumnScan16Bytes)
{
constexpr const uint8_t W = 16;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
IntegralType* results;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::DECIMAL;
in->OutputType = OT_DATAVALUE;
in->NOPS = 0;
in->BOP = BOP_OR;
in->NVALS = 0;
pp.setBlockPtr((int*) readBlockFromLiteralArray("col16block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<IntegralType>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, 511);
// I was not able to use datatypes::TSInt128 static member so I used this
int128_t NullValue = int128_t(0x8000000000000000LL) << 64;
ASSERT_EQ(results[0], NullValue);
for (i = 1; i < out->NVALS; ++i)
ASSERT_EQ(results[i], i+1);
EXPECT_EQ(out->Max, __col16block_cdf_umax);
EXPECT_EQ(out->Min, __col16block_cdf_umin);
}
TEST_F(ColumnScanFilterTest, ColumnScan16Bytes2CompFilters) TEST_F(ColumnScanFilterTest, ColumnScan16Bytes2CompFilters)
{ {
//TBD constexpr const uint8_t W = 16;
using IntegralType = datatypes::WidthToSIntegralType<W>::type;
IntegralType* results;
IntegralType tmp;
in->colType.DataSize = W;
in->colType.DataType = SystemCatalog::DECIMAL;
in->OutputType = OT_DATAVALUE;
in->NOPS = 2;
in->BOP = BOP_OR;
in->NVALS = 0;
tmp = 10;
args->COP = COMPARE_EQ;
memcpy(args->val, &tmp, in->colType.DataSize);
args = reinterpret_cast<ColArgs*>(&input[sizeof(NewColRequestHeader) +
sizeof(ColArgs) + in->colType.DataSize]);
args->COP = COMPARE_EQ;
tmp = 510;
memcpy(args->val, &tmp, in->colType.DataSize);
pp.setBlockPtr((int*) readBlockFromLiteralArray("col16block.cdf", block));
pp.columnScanAndFilter<IntegralType>(in, out);
results = getValuesArrayPosition<IntegralType>(getFirstValueArrayPosition(out), 0);
ASSERT_EQ(out->NVALS, 2);
ASSERT_EQ(results[0], 10);
ASSERT_EQ(results[1], 510);
EXPECT_EQ(out->Max, __col16block_cdf_umax);
EXPECT_EQ(out->Min, __col16block_cdf_umin);
} }
// vim:ts=2 sw=2: // vim:ts=2 sw=2:

View File

@ -0,0 +1,430 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <iostream>
#include <gtest/gtest.h>
#include <benchmark/benchmark.h>
#include "datatypes/mcs_datatype.h"
#include "stats.h"
#include "primitives/linux-port/primitiveprocessor.h"
#include "col1block.h"
#include "col2block.h"
#include "col4block.h"
#include "col8block.h"
#include "col_float_block.h"
#include "col_double_block.h"
#include "col_neg_float.h"
#include "col_neg_double.h"
using namespace primitives;
using namespace datatypes;
using namespace std;
// TODO Use FastOperation() to speed up run loop
uint8_t* readBlockFromLiteralArray(const std::string& fileName, uint8_t* block)
{
if (fileName == std::string("col1block.cdf"))
return &__col1block_cdf[0];
else if (fileName == std::string("col2block.cdf"))
return &__col2block_cdf[0];
else if (fileName == std::string("col4block.cdf"))
return &__col4block_cdf[0];
else if (fileName == std::string("col8block.cdf"))
return &___bin_col8block_cdf[0];
else if (fileName == std::string("col_float_block.cdf"))
return &___bin_col_float_block_cdf[0];
else if (fileName == std::string("col_double_block.cdf"))
return &___bin_col_double_block_cdf[0];
else if (fileName == std::string("col_neg_float.cdf"))
return &___bin_col_neg_float_cdf[0];
else if (fileName == std::string("col_neg_double.cdf"))
return &___bin_col_neg_double_cdf[0];
return nullptr;
}
class FilterBenchFixture : public benchmark::Fixture
{
public:
PrimitiveProcessor pp;
uint8_t input[BLOCK_SIZE];
uint8_t output[4 * BLOCK_SIZE];
uint8_t block[BLOCK_SIZE];
uint16_t* rids;
uint32_t i;
uint32_t written;
NewColRequestHeader* in;
ColResultHeader* out;
ColArgs* args;
void SetUp(benchmark::State& state)
{
memset(input, 0, BLOCK_SIZE);
memset(output, 0, 4 * BLOCK_SIZE);
in = reinterpret_cast<NewColRequestHeader*>(input);
out = reinterpret_cast<ColResultHeader*>(output);
rids = reinterpret_cast<uint16_t*>(&in[1]);
args = reinterpret_cast<ColArgs*>(&in[1]);
}
// to avoid gcc compile time warning
void SetUp(const benchmark::State& state)
{
SetUp(const_cast<benchmark::State&>(state));
}
void inTestRunSetUp(const std::string& dataName, const size_t dataSize, const uint8_t dataType, const uint32_t outputType, ColArgs* args)
{
in->colType = ColRequestHeaderDataType();
in->colType.DataSize = dataSize;
in->colType.DataType = dataType;
in->OutputType = outputType;
in->NOPS = 0;
in->NVALS = 0;
pp.setBlockPtr((int*) readBlockFromLiteralArray(dataName, block));
}
void runFilterBenchLegacy()
{
pp.p_Col(in, out, 4 * BLOCK_SIZE, &written);
}
template<int W>
void runFilterBenchTemplated()
{
using IntegralType = typename datatypes::WidthToSIntegralType<W>::type;
pp.columnScanAndFilter<IntegralType>(in, out);
}
template<int W>
void setUp1EqFilter()
{
using IntegralType = typename datatypes::WidthToSIntegralType<W>::type;
in->NOPS = 1;
in->NVALS = 0;
IntegralType tmp = 20;
args->COP = COMPARE_EQ;
memcpy(args->val, &tmp, W);
}
};
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan1ByteLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 1;
state.PauseTiming();
inTestRunSetUp("col1block.cdf", W, SystemCatalog::CHAR, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan1ByteLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan1Byte1FilterLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 1;
setUp1EqFilter<W>();
inTestRunSetUp("col1block.cdf", W, SystemCatalog::CHAR, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan1Byte1FilterLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan1ByteTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 1;
state.PauseTiming();
inTestRunSetUp("col1block.cdf", W, SystemCatalog::CHAR, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan1ByteTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan1Byte1FilterTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 1;
setUp1EqFilter<W>();
inTestRunSetUp("col1block.cdf", W, SystemCatalog::CHAR, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan1Byte1FilterTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan1ByteVectorizedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 1;
state.PauseTiming();
inTestRunSetUp("col1block.cdf", W, SystemCatalog::TINYINT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan1ByteVectorizedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan1Byte1FilterVectorizedCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 1;
setUp1EqFilter<W>();
inTestRunSetUp("col1block.cdf", W, SystemCatalog::TINYINT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan1Byte1FilterVectorizedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan2ByteLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 2;
state.PauseTiming();
inTestRunSetUp("col2block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan2ByteLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan2Byte1FilterLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 2;
setUp1EqFilter<W>();
inTestRunSetUp("col2block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan2Byte1FilterLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan2ByteTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 2;
state.PauseTiming();
inTestRunSetUp("col2block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan2ByteTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan2Byte1FilterTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 2;
setUp1EqFilter<W>();
inTestRunSetUp("col2block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan2Byte1FilterTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan2Byte1FilterVectorizedCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 2;
setUp1EqFilter<W>();
inTestRunSetUp("col2block.cdf", W, SystemCatalog::TINYINT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan2Byte1FilterVectorizedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan4ByteLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 4;
state.PauseTiming();
inTestRunSetUp("col4block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan4ByteLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan4Byte1FilterLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 4;
state.PauseTiming();
setUp1EqFilter<W>();
inTestRunSetUp("col4block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan4Byte1FilterLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan4ByteTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 4;
inTestRunSetUp("col4block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan4ByteTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan4ByteVectorizedCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 4;
setUp1EqFilter<W>();
inTestRunSetUp("col4block.cdf", W, SystemCatalog::TINYINT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan4ByteVectorizedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan8ByteLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 8;
state.PauseTiming();
inTestRunSetUp("col8block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan8ByteLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan8Byte1FilterLegacyCode)(benchmark::State& state)
{
for (auto _ : state)
{
state.PauseTiming();
constexpr const uint8_t W = 8;
setUp1EqFilter<W>();
inTestRunSetUp("col8block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchLegacy();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan8Byte1FilterLegacyCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan8ByteTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 8;
state.PauseTiming();
inTestRunSetUp("col8block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan8ByteTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan8Byte1FilterTemplatedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 8;
state.PauseTiming();
setUp1EqFilter<W>();
inTestRunSetUp("col8block.cdf", W, SystemCatalog::INT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan8Byte1FilterTemplatedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan8ByteVectorizedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 8;
state.PauseTiming();
inTestRunSetUp("col8block.cdf", W, SystemCatalog::TINYINT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan8ByteVectorizedCode);
BENCHMARK_DEFINE_F(FilterBenchFixture, BM_ColumnScan8Byte1FilterVectorizedCode)(benchmark::State& state)
{
for (auto _ : state)
{
constexpr const uint8_t W = 8;
state.PauseTiming();
setUp1EqFilter<W>();
inTestRunSetUp("col8block.cdf", W, SystemCatalog::TINYINT, OT_DATAVALUE, args);
state.ResumeTiming();
runFilterBenchTemplated<W>();
}
}
BENCHMARK_REGISTER_F(FilterBenchFixture, BM_ColumnScan8Byte1FilterVectorizedCode);
BENCHMARK_MAIN();
// vim:ts=2 sw=2:

473
utils/common/simd_sse.h Normal file
View File

@ -0,0 +1,473 @@
/* Copyright (C) 2021 Mariadb Corporation.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef UTILS_SIMD_SSE_H
#define UTILS_SIMD_SSE_H
#if defined(__x86_64__ )
#include <cstdint>
#include <type_traits>
#ifdef __OPTIMIZE__
#include <smmintrin.h>
#include <emmintrin.h>
#define MCS_FORCE_INLINE __attribute__((__always_inline__))
#else
#define __OPTIMIZE__
#include <smmintrin.h>
#include <emmintrin.h>
#undef __OPTIMIZE__
#define MCS_FORCE_INLINE inline
#endif
#include <mcs_datatype.h>
namespace simd
{
using vi128_t = __m128i;
using msk128_t = uint16_t;
using int128_t = __int128;
using MT = uint16_t;
// This ugly wrapper used to allow to use __m128i as a template class parameter argument
struct vi128_wr
{
__m128i v;
};
template<typename VT, int WIDTH>
class SimdFilterProcessor
{ };
template<>
class SimdFilterProcessor<vi128_wr, 16>
{
// This is a dummy class that is not currently used.
public:
constexpr static const uint16_t vecByteSize = 16U;
constexpr static const uint16_t vecBitSize = 128U;
using T = int128_t;
using SIMD_WRAPPER_TYPE = simd::vi128_wr;
using SIMD_TYPE = simd::vi128_t;
// Load value
MCS_FORCE_INLINE vi128_t loadValue(const T fill)
{
return _mm_loadu_si128(reinterpret_cast<const vi128_t*>(&fill));
}
// Load from
MCS_FORCE_INLINE vi128_t loadFrom(const char* from)
{
return _mm_loadu_si128(reinterpret_cast<const vi128_t*>(from));
}
MCS_FORCE_INLINE MT cmpDummy(vi128_t& x, vi128_t& y)
{
return 0xFFFF;
}
// Compare
MCS_FORCE_INLINE MT cmpEq(vi128_t& x, vi128_t& y)
{
return cmpDummy(x, y);
}
MCS_FORCE_INLINE MT cmpGe(vi128_t& x, vi128_t& y)
{
return cmpDummy(x, y);
}
MCS_FORCE_INLINE MT cmpGt(vi128_t& x, vi128_t& y)
{
return cmpDummy(x, y);
}
MCS_FORCE_INLINE MT cmpLt(vi128_t& x, vi128_t& y)
{
return cmpDummy(x, y);
}
MCS_FORCE_INLINE MT cmpLe(vi128_t& x, vi128_t& y)
{
return cmpDummy(x, y);
}
MCS_FORCE_INLINE MT cmpNe(vi128_t& x, vi128_t& y)
{
return cmpDummy(x, y);
}
MCS_FORCE_INLINE MT cmpAlwaysFalse(vi128_t& x, vi128_t& y)
{
return 0;
}
// misc
MCS_FORCE_INLINE uint16_t convertVectorToBitMask(vi128_t& vmask)
{
return _mm_movemask_epi8(vmask);
}
MCS_FORCE_INLINE vi128_t setToZero()
{
return _mm_setzero_si128();
}
// store
MCS_FORCE_INLINE void storeWMask(vi128_t& x, vi128_t& vmask, char* dst)
{
_mm_maskmoveu_si128(x, vmask, dst);
}
MCS_FORCE_INLINE void store(char* dst, vi128_t& x)
{
_mm_storeu_si128(reinterpret_cast<vi128_t*>(dst), x);
}
};
template<>
class SimdFilterProcessor<vi128_wr, 8>
{
public:
constexpr static const uint16_t vecByteSize = 16U;
constexpr static const uint16_t vecBitSize = 128U;
using T = datatypes::WidthToSIntegralType<8>::type;
using SIMD_WRAPPER_TYPE = simd::vi128_wr;
using SIMD_TYPE = simd::vi128_t;
// Load value
MCS_FORCE_INLINE vi128_t loadValue(const T fill)
{
return _mm_set_epi64x(fill, fill);
}
// Load from
MCS_FORCE_INLINE vi128_t loadFrom(const char* from)
{
return _mm_loadu_si128(reinterpret_cast<const vi128_t*>(from));
}
// Compare
MCS_FORCE_INLINE MT cmpGe(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_or_si128(_mm_cmpgt_epi64(x, y),_mm_cmpeq_epi64(x, y)));
}
MCS_FORCE_INLINE MT cmpGt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpgt_epi64(x, y));
}
MCS_FORCE_INLINE MT cmpEq(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi64(x, y));
}
MCS_FORCE_INLINE MT cmpLe(vi128_t& x, vi128_t& y)
{
return cmpGt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpLt(vi128_t& x, vi128_t& y)
{
return cmpNe(x, y) ^ cmpGt(x, y);
}
MCS_FORCE_INLINE MT cmpNe(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi64(x, y)) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpAlwaysFalse(vi128_t& x, vi128_t& y)
{
return 0;
}
// misc
MCS_FORCE_INLINE MT convertVectorToBitMask(vi128_t& vmask)
{
return _mm_movemask_epi8(vmask);
}
MCS_FORCE_INLINE vi128_t setToZero()
{
return _mm_setzero_si128();
}
// store
MCS_FORCE_INLINE void storeWMask(vi128_t& x, vi128_t& vmask, char* dst)
{
_mm_maskmoveu_si128(x, vmask, dst);
}
MCS_FORCE_INLINE void store(char* dst, vi128_t& x)
{
_mm_storeu_si128(reinterpret_cast<vi128_t*>(dst), x);
}
};
template<>
class SimdFilterProcessor<vi128_wr, 4>
{
public:
constexpr static const uint16_t vecByteSize = 16U;
constexpr static const uint16_t vecBitSize = 128U;
using T = datatypes::WidthToSIntegralType<4>::type;
using SIMD_WRAPPER_TYPE = simd::vi128_wr;
using SIMD_TYPE = simd::vi128_t;
// Load value
MCS_FORCE_INLINE vi128_t loadValue(const T fill)
{
return _mm_set1_epi32(fill);
}
// Load from
MCS_FORCE_INLINE vi128_t loadFrom(const char* from)
{
return _mm_loadu_si128(reinterpret_cast<const vi128_t*>(from));
}
// Compare
MCS_FORCE_INLINE MT cmpEq(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi32(x, y));
}
MCS_FORCE_INLINE MT cmpGe(vi128_t& x, vi128_t& y)
{
return cmpLt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpGt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpgt_epi32(x, y));
}
MCS_FORCE_INLINE MT cmpLe(vi128_t& x, vi128_t& y)
{
return cmpGt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpLt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmplt_epi32(x, y));
}
MCS_FORCE_INLINE MT cmpNe(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi32(x, y)) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpAlwaysFalse(vi128_t& x, vi128_t& y)
{
return 0;
}
// misc
MCS_FORCE_INLINE MT convertVectorToBitMask(vi128_t& vmask)
{
return _mm_movemask_epi8(vmask);
}
MCS_FORCE_INLINE vi128_t setToZero()
{
return _mm_setzero_si128();
}
// store
MCS_FORCE_INLINE void storeWMask(vi128_t& x, vi128_t& vmask, char* dst)
{
_mm_maskmoveu_si128(x, vmask, dst);
}
MCS_FORCE_INLINE void store(char* dst, vi128_t& x)
{
_mm_storeu_si128(reinterpret_cast<vi128_t*>(dst), x);
}
};
template<>
class SimdFilterProcessor<vi128_wr, 2>
{
public:
constexpr static const uint16_t vecByteSize = 16U;
constexpr static const uint16_t vecBitSize = 128U;
using T = datatypes::WidthToSIntegralType<2>::type;
using SIMD_WRAPPER_TYPE = simd::vi128_wr;
using SIMD_TYPE = simd::vi128_t;
// Load value
MCS_FORCE_INLINE vi128_t loadValue(const T fill)
{
return _mm_set1_epi16(fill);
}
// Load from
MCS_FORCE_INLINE vi128_t loadFrom(const char* from)
{
return _mm_loadu_si128(reinterpret_cast<const vi128_t*>(from));
}
// Compare
MCS_FORCE_INLINE MT cmpEq(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi16(x, y));
}
MCS_FORCE_INLINE MT cmpGe(vi128_t& x, vi128_t& y)
{
return cmpLt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpGt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpgt_epi16(x, y));
}
MCS_FORCE_INLINE MT cmpLe(vi128_t& x, vi128_t& y)
{
return cmpGt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpLt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmplt_epi16(x, y));
}
MCS_FORCE_INLINE MT cmpNe(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi16(x, y)) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpAlwaysFalse(vi128_t& x, vi128_t& y)
{
return 0;
}
// misc
MCS_FORCE_INLINE MT convertVectorToBitMask(vi128_t& vmask)
{
return _mm_movemask_epi8(vmask);
}
MCS_FORCE_INLINE vi128_t setToZero()
{
return _mm_setzero_si128();
}
// store
MCS_FORCE_INLINE void storeWMask(vi128_t& x, vi128_t& vmask, char* dst)
{
_mm_maskmoveu_si128(x, vmask, dst);
}
MCS_FORCE_INLINE void store(char* dst, vi128_t& x)
{
_mm_storeu_si128(reinterpret_cast<vi128_t*>(dst), x);
}
};
template<>
class SimdFilterProcessor<vi128_wr, 1>
{
public:
constexpr static const uint16_t vecByteSize = 16U;
constexpr static const uint16_t vecBitSize = 128U;
using T = datatypes::WidthToSIntegralType<1>::type;
using SIMD_WRAPPER_TYPE = simd::vi128_wr;
using SIMD_TYPE = simd::vi128_t;
// Load value
MCS_FORCE_INLINE vi128_t loadValue(const T fill)
{
return _mm_set1_epi8(fill);
}
// Load from
MCS_FORCE_INLINE vi128_t loadFrom(const char* from)
{
return _mm_loadu_si128(reinterpret_cast<const vi128_t*>(from));
}
// Compare
MCS_FORCE_INLINE MT cmpEq(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi8(x, y));
}
MCS_FORCE_INLINE MT cmpGe(vi128_t& x, vi128_t& y)
{
return cmpLt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpGt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpgt_epi8(x, y));
}
MCS_FORCE_INLINE MT cmpLe(vi128_t& x, vi128_t& y)
{
return cmpGt(x, y) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpLt(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmplt_epi8(x, y));
}
MCS_FORCE_INLINE MT cmpNe(vi128_t& x, vi128_t& y)
{
return _mm_movemask_epi8(_mm_cmpeq_epi8(x, y)) ^ 0xFFFF;
}
MCS_FORCE_INLINE MT cmpAlwaysFalse(vi128_t& x, vi128_t& y)
{
return 0;
}
// permute
/* TODO Available in AVX-512
MCS_FORCE_INLINE vi128_t perm8Bits(vi128_t& x, vi128_t& idx)
{
return _mm_permutexvar_epi8(x, idx);
}
*/
// misc
MCS_FORCE_INLINE MT convertVectorToBitMask(vi128_t& vmask)
{
return _mm_movemask_epi8(vmask);
}
MCS_FORCE_INLINE vi128_t setToZero()
{
return _mm_setzero_si128();
}
// store
MCS_FORCE_INLINE void storeWMask(vi128_t& x, vi128_t& vmask, char* dst)
{
_mm_maskmoveu_si128(x, vmask, dst);
}
MCS_FORCE_INLINE void store(char* dst, vi128_t& x)
{
_mm_storeu_si128(reinterpret_cast<vi128_t*>(dst), x);
}
};
} // end of simd
#endif // if defined(__x86_64__ )
#endif
// vim:ts=2 sw=2:

View File

@ -1287,7 +1287,6 @@ uint8_t WE_DMLCommandProc::processBatchInsert(messageqcpp::ByteStream& bs, std::
// call the write engine to write the rows // call the write engine to write the rows
int error = NO_ERROR; int error = NO_ERROR;
//fWriteEngine.setDebugLevel(WriteEngine::DEBUG_3);
if (colValuesList.size() > 0) if (colValuesList.size() > 0)
{ {
if (colValuesList[0].size() > 0) if (colValuesList[0].size() > 0)

View File

@ -283,7 +283,6 @@ int DbFileOp::writeDBFile( CommBlock& cb, const unsigned char* writeBuf,
{ {
CacheKey key; CacheKey key;
int ret; int ret;
if ( Cache::getUseCache() ) if ( Cache::getUseCache() )
{ {
if ( Cache::cacheKeyExist( cb.file.oid, lbid ) ) if ( Cache::cacheKeyExist( cb.file.oid, lbid ) )

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2014 InfiniDB, Inc. /* Copyright (C) 2014 InfiniDB, Inc.
Copyright (C) 2016-2021 MariaDB Corporation
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2014 InfiniDB, Inc. /* Copyright (C) 2014 InfiniDB, Inc.
Copyright (C) 2016-2021 MariaDB Corporation
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License

View File

@ -26,6 +26,7 @@
#include <unistd.h> #include <unistd.h>
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <unordered_map>
using namespace std; using namespace std;
#include "joblisttypes.h" #include "joblisttypes.h"
@ -70,6 +71,7 @@ namespace WriteEngine
{ {
StopWatch timer; StopWatch timer;
using OidToIdxMap = std::unordered_map<OID, ColStructList::size_type>;
/**@brief WriteEngineWrapper Constructor /**@brief WriteEngineWrapper Constructor
*/ */
@ -1323,7 +1325,7 @@ int WriteEngineWrapper::insertColumnRecs(const TxnID& txnid,
// debug information for testing // debug information for testing
if (isDebug(DEBUG_2)) if (isDebug(DEBUG_2))
{ {
printInputValue(colStructList, colValueList, ridList); printInputValue(colStructList, colValueList, ridList, dctnryStructList, dictStrList);
} }
// end // end
@ -2869,7 +2871,7 @@ int WriteEngineWrapper::insertColumnRec_SYS(const TxnID& txnid,
// debug information for testing // debug information for testing
if (isDebug(DEBUG_2)) if (isDebug(DEBUG_2))
{ {
printInputValue(colStructList, colValueList, ridList); printInputValue(colStructList, colValueList, ridList, dctnryStructList, dictStrList);
} }
// end // end
@ -3531,7 +3533,7 @@ int WriteEngineWrapper::insertColumnRec_Single(const TxnID& txnid,
// debug information for testing // debug information for testing
if (isDebug(DEBUG_2)) if (isDebug(DEBUG_2))
{ {
printInputValue(colStructList, colValueList, ridList); printInputValue(colStructList, colValueList, ridList, dctnryStructList, dictStrList);
} }
//Convert data type and column width to write engine specific //Convert data type and column width to write engine specific
@ -4188,35 +4190,41 @@ int WriteEngineWrapper::insertColumnRec_Single(const TxnID& txnid,
***********************************************************/ ***********************************************************/
void WriteEngineWrapper::printInputValue(const ColStructList& colStructList, void WriteEngineWrapper::printInputValue(const ColStructList& colStructList,
const ColValueList& colValueList, const ColValueList& colValueList,
const RIDList& ridList) const const RIDList& ridList,
const DctnryStructList& dctnryStructList,
const DictStrList& dictStrList) const
{ {
ColTupleList curTupleList; ColTupleList curTupleList;
ColStruct curColStruct; ColStruct curColStruct;
ColTuple curTuple; ColTuple curTuple;
string curStr; string curStr;
ColStructList::size_type i; ColStructList::size_type i;
ColTupleList::size_type j; size_t j;
OidToIdxMap oidToIdxMap;
printf("\n=========================\n"); std::cerr << std::endl << "=========================" << std::endl;
// printf("\nTable OID : %d \n", tableOid);
printf("\nTotal RIDs: %zu\n", ridList.size()); std::cerr << "Total RIDs: " << ridList.size() << std::endl;
for (i = 0; i < ridList.size(); i++) for (i = 0; i < ridList.size(); i++)
cout << "RID[" << i << "] : " << ridList[i] << "\n"; std::cerr << "RID[" << i << "] : " << ridList[i] << std::endl;
printf("\nTotal Columns: %zu\n", colStructList.size());
std::cerr << "Total Columns: " << colStructList.size() << std::endl;
for (i = 0; i < colStructList.size(); i++) for (i = 0; i < colStructList.size(); i++)
{ {
curColStruct = colStructList[i]; curColStruct = colStructList[i];
curTupleList = colValueList[i]; curTupleList = colValueList[i];
if (curColStruct.tokenFlag)
{
oidToIdxMap.insert({curColStruct.dataOid, i});
continue;
}
printf("\nColumn[%zu]", i); std::cerr << "Column[" << i << "]";
printf("\nData file OID : %d \t", curColStruct.dataOid); std::cerr << "Data file OID : " << curColStruct.dataOid << "\t";
printf("\tWidth : %d \t Type: %d", curColStruct.colWidth, curColStruct.colDataType); std::cerr << "Width : " << curColStruct.colWidth << "\t" << " Type: " << curColStruct.colDataType << std::endl;
printf("\nTotal values : %zu \n", curTupleList.size()); std::cerr << "Total values : " << curTupleList.size() << std::endl;
for (j = 0; j < curTupleList.size(); j++) for (j = 0; j < curTupleList.size(); j++)
{ {
@ -4226,19 +4234,22 @@ void WriteEngineWrapper::printInputValue(const ColStructList& colStructList,
{ {
if (curTuple.data.type() == typeid(int)) if (curTuple.data.type() == typeid(int))
curStr = boost::lexical_cast<string>(boost::any_cast<int>(curTuple.data)); curStr = boost::lexical_cast<string>(boost::any_cast<int>(curTuple.data));
else if (curTuple.data.type() == typeid(unsigned int))
curStr = boost::lexical_cast<string>(boost::any_cast<unsigned int>(curTuple.data));
else if (curTuple.data.type() == typeid(float)) else if (curTuple.data.type() == typeid(float))
curStr = boost::lexical_cast<string>(boost::any_cast<float>(curTuple.data)); curStr = boost::lexical_cast<string>(boost::any_cast<float>(curTuple.data));
else if (curTuple.data.type() == typeid(long long)) else if (curTuple.data.type() == typeid(long long))
curStr = boost::lexical_cast<string>(boost::any_cast<long long>(curTuple.data)); curStr = boost::lexical_cast<string>(boost::any_cast<long long>(curTuple.data));
else if (curTuple.data.type() == typeid(unsigned long long))
curStr = boost::lexical_cast<string>(boost::any_cast<unsigned long long>(curTuple.data));
else if (curTuple.data.type() == typeid(int128_t)) else if (curTuple.data.type() == typeid(int128_t))
{ curStr = datatypes::TSInt128(boost::any_cast<int128_t>(curTuple.data)).toString();
datatypes::TSInt128 val(boost::any_cast<int128_t>(curTuple.data));
curStr = val.toString();
}
else if (curTuple.data.type() == typeid(double)) else if (curTuple.data.type() == typeid(double))
curStr = boost::lexical_cast<string>(boost::any_cast<double>(curTuple.data)); curStr = boost::lexical_cast<string>(boost::any_cast<double>(curTuple.data));
else if (curTuple.data.type() == typeid(short)) else if (curTuple.data.type() == typeid(short))
curStr = boost::lexical_cast<string>(boost::any_cast<short>(curTuple.data)); curStr = boost::lexical_cast<string>(boost::any_cast<short>(curTuple.data));
else if (curTuple.data.type() == typeid(unsigned short))
curStr = boost::lexical_cast<string>(boost::any_cast<unsigned short>(curTuple.data));
else if (curTuple.data.type() == typeid(char)) else if (curTuple.data.type() == typeid(char))
curStr = boost::lexical_cast<string>(boost::any_cast<char>(curTuple.data)); curStr = boost::lexical_cast<string>(boost::any_cast<char>(curTuple.data));
else else
@ -4249,12 +4260,36 @@ void WriteEngineWrapper::printInputValue(const ColStructList& colStructList,
} }
if (isDebug(DEBUG_3)) if (isDebug(DEBUG_3))
printf("Value[%zu] : %s\n", j, curStr.c_str()); std::cerr << "Value[" << j << "]: " << curStr.c_str() << std::endl;
}
}
for (i = 0; i < dctnryStructList.size(); ++i)
{
if (dctnryStructList[i].dctnryOid == 0)
continue;
std::cerr << "Dict[" << i << "]";
std::cerr << " file OID : " << dctnryStructList[i].dctnryOid << " Token file OID: " << dctnryStructList[i].columnOid << "\t";
std::cerr << "Width : " << dctnryStructList[i].colWidth << "\t" << " Type: " << dctnryStructList[i].fCompressionType << std::endl;
std::cerr << "Total values : " << dictStrList.size() << std::endl;
if (isDebug(DEBUG_3))
{
for (j = 0; j < dictStrList[i].size(); ++j)
{
// We presume there will be a value.
auto tokenOidIdx = oidToIdxMap[dctnryStructList[i].columnOid];
std::cerr << "string [" << dictStrList[i][j] << "]" << std::endl;
bool isToken = colStructList[tokenOidIdx].colType == WriteEngine::WR_TOKEN &&
colStructList[tokenOidIdx].tokenFlag;
if (isToken && !colValueList[tokenOidIdx][j].data.empty())
{
Token t = boost::any_cast<Token>(colValueList[tokenOidIdx][j].data);
std::cerr << "Token: block pos:[" << t.op << "] fbo: [" << t.fbo << "] bc: [" << t.bc << "]" << std::endl;
}
}
} }
} }
printf("\n=========================\n"); std::cerr << "=========================" << std::endl;
} }
/*********************************************************** /***********************************************************
@ -6046,7 +6081,6 @@ int WriteEngineWrapper::tokenize(const TxnID& txnid, DctnryTuple& dctnryTuple, i
{ {
int cop = op(ct); int cop = op(ct);
m_dctnry[cop]->setTransId(txnid); m_dctnry[cop]->setTransId(txnid);
//cout << "Tokenizing dctnryTuple.sigValue " << dctnryTuple.sigValue << endl;
return m_dctnry[cop]->updateDctnry(dctnryTuple.sigValue, dctnryTuple.sigSize, dctnryTuple.token); return m_dctnry[cop]->updateDctnry(dctnryTuple.sigValue, dctnryTuple.sigSize, dctnryTuple.token);
} }

View File

@ -716,7 +716,7 @@ private:
/** /**
* @brief Print input value from DDL/DML processors * @brief Print input value from DDL/DML processors
*/ */
void printInputValue(const ColStructList& colStructList, const ColValueList& colValueList, const RIDList& ridList) const; void printInputValue(const ColStructList& colStructList, const ColValueList& colValueList, const RIDList& ridList, const DctnryStructList& dctnryStructList, const DictStrList& dictStrList) const;
/** /**
* @brief Process version buffer * @brief Process version buffer
@ -826,7 +826,6 @@ private:
ColumnOp* m_colOp[TOTAL_COMPRESS_OP]; // column operations ColumnOp* m_colOp[TOTAL_COMPRESS_OP]; // column operations
Dctnry* m_dctnry[TOTAL_COMPRESS_OP]; // dictionary operations Dctnry* m_dctnry[TOTAL_COMPRESS_OP]; // dictionary operations
OpType m_opType; // operation type OpType m_opType; // operation type
DebugLevel m_debugLevel; // debug level
}; };
} //end of namespace } //end of namespace