You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2026-10-23 21:49:05 +03:00
Fix/mcol 5787 rgdata buffer max size dev (#3325)
* fix(rowgroup): RGData now uses uint64_t counter for the fixed sizes columns data buf. The buffer can utilize > 4GB RAM that is necessary for PM side join. RGData ctor uses uint32_t allocating data buffer. This fact causes implicit heap overflow. * feat(bytestream,serdes): BS buffer size type is uint64_t This necessary to handle 64bit RGData, that comes as a separate patch. The pair of patches would allow to have PM joins when SmallSide size > 4GB. * feat(bytestream,serdes): Distribute BS buf size data type change to avoid implicit data type narrowing * feat(rowgroup): this returns bits lost during cherry-pick. The bits lost caused the first RGData::serialize to crash a process
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include "SocketPool.h"
|
||||
#include "bytestream.h"
|
||||
#include "configcpp.h"
|
||||
#include "logger.h"
|
||||
#include "messageFormat.h"
|
||||
@@ -87,8 +88,8 @@ SocketPool::~SocketPool()
|
||||
|
||||
int SocketPool::send_recv(messageqcpp::ByteStream& in, messageqcpp::ByteStream* out)
|
||||
{
|
||||
uint count = 0;
|
||||
uint length = in.length();
|
||||
messageqcpp::BSSizeType count = 0;
|
||||
messageqcpp::BSSizeType length = in.length();
|
||||
int sock = -1;
|
||||
const uint8_t* inbuf = in.buf();
|
||||
ssize_t err = 0;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include "bytestream.h"
|
||||
#define _CRT_RAND_S // for win rand_s
|
||||
#include <unistd.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -804,7 +805,7 @@ uint64_t JoinPartition::writeByteStream(int which, ByteStream& bs)
|
||||
}
|
||||
|
||||
uint64_t ret = 0;
|
||||
size_t len = bs.length();
|
||||
BSSizeType len = bs.length();
|
||||
idbassert(len != 0);
|
||||
|
||||
fs.seekp(offset);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (C) 2014 InfiniDB, Inc.
|
||||
Copyright (C) 2019 MariaDB Corporation
|
||||
Copyright (C) 2019-2024 MariaDB Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
@@ -46,7 +46,7 @@ namespace messageqcpp
|
||||
/* Copies only the data left to be read */
|
||||
void ByteStream::doCopy(const ByteStream& rhs)
|
||||
{
|
||||
uint32_t rlen = rhs.length();
|
||||
BSSizeType rlen = rhs.length();
|
||||
|
||||
if (fMaxLen < rlen)
|
||||
{
|
||||
@@ -94,7 +94,7 @@ ByteStream& ByteStream::operator=(const ByteStream& rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteStream::ByteStream(uint32_t initSize) : fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
|
||||
ByteStream::ByteStream(BSSizeType initSize) : fBuf(0), fCurInPtr(0), fCurOutPtr(0), fMaxLen(0)
|
||||
{
|
||||
if (initSize > 0)
|
||||
growBuf(initSize);
|
||||
@@ -102,13 +102,13 @@ ByteStream::ByteStream(uint32_t initSize) : fBuf(0), fCurInPtr(0), fCurOutPtr(0)
|
||||
|
||||
void ByteStream::add(const uint8_t b)
|
||||
{
|
||||
if (fBuf == 0 || (static_cast<uint32_t>(fCurInPtr - fBuf) == fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (static_cast<BSSizeType>(fCurInPtr - fBuf) == fMaxLen + ISSOverhead))
|
||||
growBuf();
|
||||
|
||||
*fCurInPtr++ = b;
|
||||
}
|
||||
|
||||
void ByteStream::growBuf(uint32_t toSize)
|
||||
void ByteStream::growBuf(BSSizeType toSize)
|
||||
{
|
||||
if (fBuf == 0)
|
||||
{
|
||||
@@ -138,8 +138,8 @@ void ByteStream::growBuf(uint32_t toSize)
|
||||
toSize = std::max(toSize, fMaxLen * 2);
|
||||
|
||||
uint8_t* t = new uint8_t[toSize + ISSOverhead];
|
||||
uint32_t curOutOff = fCurOutPtr - fBuf;
|
||||
uint32_t curInOff = fCurInPtr - fBuf;
|
||||
BSSizeType curOutOff = fCurOutPtr - fBuf;
|
||||
BSSizeType curInOff = fCurInPtr - fBuf;
|
||||
memcpy(t, fBuf, fCurInPtr - fBuf);
|
||||
#ifdef ZERO_ON_NEW
|
||||
memset(t + (fCurInPtr - fBuf), 0, (toSize + ISSOverhead) - (fCurInPtr - fBuf));
|
||||
@@ -169,7 +169,7 @@ void ByteStream::setLongStrings(const std::vector<std::shared_ptr<uint8_t[]>>& o
|
||||
|
||||
ByteStream& ByteStream::operator<<(const int8_t b)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 1U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(b) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((int8_t*)fCurInPtr) = b;
|
||||
@@ -187,7 +187,7 @@ ByteStream& ByteStream::operator<<(const uint8_t b)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const int16_t d)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 2U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(d) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((int16_t*)fCurInPtr) = d;
|
||||
@@ -198,7 +198,7 @@ ByteStream& ByteStream::operator<<(const int16_t d)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const uint16_t d)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 2U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(d) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((uint16_t*)fCurInPtr) = d;
|
||||
@@ -209,7 +209,7 @@ ByteStream& ByteStream::operator<<(const uint16_t d)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const int32_t q)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(q) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((int32_t*)fCurInPtr) = q;
|
||||
@@ -220,7 +220,7 @@ ByteStream& ByteStream::operator<<(const int32_t q)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const uint32_t q)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 4U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(q) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((uint32_t*)fCurInPtr) = q;
|
||||
@@ -231,7 +231,7 @@ ByteStream& ByteStream::operator<<(const uint32_t q)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const int64_t o)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 8U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(o) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((int64_t*)fCurInPtr) = o;
|
||||
@@ -242,7 +242,7 @@ ByteStream& ByteStream::operator<<(const int64_t o)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const uint64_t o)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 8U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(o) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
*((uint64_t*)fCurInPtr) = o;
|
||||
@@ -251,20 +251,20 @@ ByteStream& ByteStream::operator<<(const uint64_t o)
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteStream& ByteStream::operator<<(const uint128_t& o)
|
||||
ByteStream& ByteStream::operator<<(const uint128_t& h)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 16U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(h) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
datatypes::TSInt128::storeUnaligned(fCurInPtr, o);
|
||||
datatypes::TSInt128::storeUnaligned(fCurInPtr, h);
|
||||
fCurInPtr += 16;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteStream& ByteStream::operator<<(const int128_t& o)
|
||||
ByteStream& ByteStream::operator<<(const int128_t& h)
|
||||
{
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + 16U > fMaxLen + ISSOverhead))
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sizeof(h) > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
datatypes::TSInt128::storeUnaligned(fCurInPtr, o);
|
||||
datatypes::TSInt128::storeUnaligned(fCurInPtr, h);
|
||||
fCurInPtr += 16;
|
||||
return *this;
|
||||
}
|
||||
@@ -475,18 +475,18 @@ void ByteStream::peek(uint64_t& o) const
|
||||
o = *((uint64_t*)fCurOutPtr);
|
||||
}
|
||||
|
||||
void ByteStream::peek(uint128_t& o) const
|
||||
void ByteStream::peek(uint128_t& h) const
|
||||
{
|
||||
if (length() < 16)
|
||||
throw underflow_error("ByteStream>uint128_t: not enough data in stream to fill datatype");
|
||||
datatypes::TSInt128::assignPtrPtr(&o, fCurOutPtr);
|
||||
datatypes::TSInt128::assignPtrPtr(&h, fCurOutPtr);
|
||||
}
|
||||
|
||||
void ByteStream::peek(int128_t& o) const
|
||||
void ByteStream::peek(int128_t& h) const
|
||||
{
|
||||
if (length() < 16)
|
||||
throw underflow_error("ByteStream>int128_t: not enough data in stream to fill datatype");
|
||||
datatypes::TSInt128::assignPtrPtr(&o, fCurOutPtr);
|
||||
datatypes::TSInt128::assignPtrPtr(&h, fCurOutPtr);
|
||||
}
|
||||
|
||||
void ByteStream::peek(string& s) const
|
||||
@@ -519,7 +519,7 @@ void ByteStream::peek(string& s) const
|
||||
throw logging::ProtocolError("expected a string");
|
||||
|
||||
// we know len >= 0 by now...
|
||||
if (length() < static_cast<uint32_t>(len + 4))
|
||||
if (length() < static_cast<BSSizeType>(len + 4))
|
||||
{
|
||||
#if DEBUG_DUMP_STRINGS_LESS_THAN > 0
|
||||
cerr << "bs: wanted " << len + 4 << " bytes, but there are only " << length() << " remaining" << endl;
|
||||
@@ -531,13 +531,13 @@ void ByteStream::peek(string& s) const
|
||||
s.assign((char*)&fCurOutPtr[4], len);
|
||||
}
|
||||
|
||||
void ByteStream::load(const uint8_t* bp, uint32_t len)
|
||||
void ByteStream::load(const uint8_t* bp, BSSizeType len)
|
||||
{
|
||||
// Do all the stuff that could throw an exception first
|
||||
if (bp == 0 && len != 0)
|
||||
throw invalid_argument("ByteStream::load: bp cannot equal 0 when len is not equal to 0");
|
||||
|
||||
uint32_t newMaxLen = (len + BlockSize - 1) / BlockSize * BlockSize;
|
||||
BSSizeType newMaxLen = (len + BlockSize - 1) / BlockSize * BlockSize;
|
||||
|
||||
if (len > fMaxLen)
|
||||
{
|
||||
@@ -551,7 +551,7 @@ void ByteStream::load(const uint8_t* bp, uint32_t len)
|
||||
fCurInPtr = fBuf + len + ISSOverhead;
|
||||
}
|
||||
|
||||
void ByteStream::append(const uint8_t* bp, uint32_t len)
|
||||
void ByteStream::append(const uint8_t* bp, BSSizeType len)
|
||||
{
|
||||
if (len == 0)
|
||||
return;
|
||||
@@ -559,7 +559,7 @@ void ByteStream::append(const uint8_t* bp, uint32_t len)
|
||||
if (bp == 0)
|
||||
throw invalid_argument("ByteStream::append: bp cannot equal 0 when len is not equal to 0");
|
||||
|
||||
uint32_t newSize = static_cast<uint32_t>(fCurInPtr - fBuf + len);
|
||||
BSSizeType newSize = static_cast<BSSizeType>(fCurInPtr - fBuf + len);
|
||||
|
||||
if (fBuf == 0 || (newSize > fMaxLen))
|
||||
growBuf(newSize);
|
||||
@@ -635,7 +635,7 @@ void ByteStream::serialize(ByteStream& bs) const
|
||||
|
||||
void ByteStream::deserialize(ByteStream& bs)
|
||||
{
|
||||
uint32_t len;
|
||||
BSSizeType len;
|
||||
|
||||
restart();
|
||||
bs >> len;
|
||||
@@ -643,9 +643,9 @@ void ByteStream::deserialize(ByteStream& bs)
|
||||
bs.advance(len);
|
||||
}
|
||||
|
||||
void ByteStream::needAtLeast(size_t amount)
|
||||
void ByteStream::needAtLeast(BSSizeType amount)
|
||||
{
|
||||
size_t currentSpace;
|
||||
BSSizeType currentSpace;
|
||||
|
||||
currentSpace = fMaxLen - (fCurInPtr - (fBuf + ISSOverhead));
|
||||
|
||||
@@ -656,7 +656,7 @@ void ByteStream::needAtLeast(size_t amount)
|
||||
|
||||
ByteStream& ByteStream::operator<<(const ByteStream& bs)
|
||||
{
|
||||
uint32_t len = bs.length();
|
||||
BSSizeType len = bs.length();
|
||||
|
||||
*this << len;
|
||||
|
||||
@@ -668,20 +668,20 @@ ByteStream& ByteStream::operator<<(const ByteStream& bs)
|
||||
ByteStream& ByteStream::operator>>(ByteStream& bs)
|
||||
{
|
||||
peek(bs);
|
||||
fCurOutPtr += 4 + bs.length();
|
||||
fCurOutPtr += sizeof(BSSizeType) + bs.length();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ByteStream::peek(ByteStream& bs) const
|
||||
{
|
||||
uint32_t len;
|
||||
BSSizeType len;
|
||||
|
||||
peek(len);
|
||||
|
||||
if (length() < len)
|
||||
throw underflow_error("ByteStream>ByteStream: not enough data in stream to fill datatype");
|
||||
|
||||
bs.load(&fCurOutPtr[4], len);
|
||||
bs.load(&fCurOutPtr[sizeof(len)], len);
|
||||
}
|
||||
|
||||
ByteStream& ByteStream::operator<<(const uuid& u)
|
||||
@@ -707,7 +707,7 @@ void ByteStream::peek(uuid& u) const
|
||||
|
||||
ByteStream& ByteStream::operator<<(const float f)
|
||||
{
|
||||
int sz = sizeof(float);
|
||||
const constexpr BSSizeType sz = sizeof(float);
|
||||
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
@@ -719,7 +719,7 @@ ByteStream& ByteStream::operator<<(const float f)
|
||||
}
|
||||
ByteStream& ByteStream::operator<<(const double d)
|
||||
{
|
||||
int sz = sizeof(double);
|
||||
const constexpr BSSizeType sz = sizeof(double);
|
||||
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
@@ -731,7 +731,7 @@ ByteStream& ByteStream::operator<<(const double d)
|
||||
}
|
||||
ByteStream& ByteStream::operator<<(const long double d)
|
||||
{
|
||||
int sz = sizeof(long double);
|
||||
const constexpr BSSizeType sz = sizeof(long double);
|
||||
|
||||
if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead))
|
||||
growBuf(fMaxLen + BlockSize);
|
||||
|
||||
@@ -45,6 +45,7 @@ class ByteStreamTestSuite;
|
||||
namespace messageqcpp
|
||||
{
|
||||
typedef boost::shared_ptr<ByteStream> SBS;
|
||||
using BSSizeType = uint64_t;
|
||||
|
||||
/**
|
||||
* @brief A class to marshall bytes as a stream
|
||||
@@ -76,11 +77,11 @@ class ByteStream : public Serializeable
|
||||
/**
|
||||
* default ctor
|
||||
*/
|
||||
EXPORT explicit ByteStream(uint32_t initSize = 8192); // multiples of pagesize are best
|
||||
EXPORT explicit ByteStream(BSSizeType initSize = 8192); // multiples of pagesize are best
|
||||
/**
|
||||
* ctor with a uint8_t array and len initializer
|
||||
*/
|
||||
inline ByteStream(const uint8_t* bp, const uint32_t len);
|
||||
inline ByteStream(const uint8_t* bp, const BSSizeType len);
|
||||
/**
|
||||
* copy ctor
|
||||
*/
|
||||
@@ -337,12 +338,12 @@ class ByteStream : public Serializeable
|
||||
/**
|
||||
* load the stream from an array. Clears out any previous data.
|
||||
*/
|
||||
EXPORT void load(const uint8_t* bp, uint32_t len);
|
||||
EXPORT void load(const uint8_t* bp, BSSizeType len);
|
||||
|
||||
/**
|
||||
* append bytes to the end of the stream.
|
||||
*/
|
||||
EXPORT void append(const uint8_t* bp, uint32_t len);
|
||||
EXPORT void append(const uint8_t* bp, BSSizeType len);
|
||||
|
||||
/**
|
||||
* equality check on buffer contents.
|
||||
@@ -378,19 +379,19 @@ class ByteStream : public Serializeable
|
||||
* advance the output ptr without having to extract bytes
|
||||
* @warning be careful advancing near 4GB!
|
||||
*/
|
||||
inline void advance(uint32_t amt);
|
||||
inline void advance(BSSizeType amt);
|
||||
|
||||
/**
|
||||
* returns the length of the queue (in bytes)
|
||||
* @warning do not attempt to make a ByteStream bigger than 4GB!
|
||||
*/
|
||||
inline uint32_t length() const;
|
||||
inline BSSizeType length() const;
|
||||
inline bool empty() const;
|
||||
|
||||
/**
|
||||
* returns the length of the queue, including header overhead (in bytes)
|
||||
*/
|
||||
inline uint32_t lengthWithHdrOverhead() const;
|
||||
inline BSSizeType lengthWithHdrOverhead() const;
|
||||
|
||||
/**
|
||||
* clears the stream. Releases any current stream and sets all pointers to 0. The state of the object
|
||||
@@ -422,7 +423,7 @@ class ByteStream : public Serializeable
|
||||
/**
|
||||
* Get the allocated size of the buffer.
|
||||
*/
|
||||
inline uint32_t getBufferSize() const;
|
||||
inline BSSizeType getBufferSize() const;
|
||||
|
||||
/**
|
||||
* Serializeable interface
|
||||
@@ -437,10 +438,10 @@ class ByteStream : public Serializeable
|
||||
/**
|
||||
* memory allocation chunk size
|
||||
*/
|
||||
EXPORT static const uint32_t BlockSize = 4096;
|
||||
EXPORT static const BSSizeType BlockSize = 4096;
|
||||
|
||||
/** size of the space we want in front of the data */
|
||||
EXPORT static const uint32_t ISSOverhead =
|
||||
EXPORT static const BSSizeType ISSOverhead =
|
||||
3 * sizeof(uint32_t); // space for the BS magic & length & number of long strings.
|
||||
|
||||
// Methods to get and set `long strings`.
|
||||
@@ -458,7 +459,7 @@ class ByteStream : public Serializeable
|
||||
/**
|
||||
* adds another BlockSize bytes to the internal buffer
|
||||
*/
|
||||
void growBuf(uint32_t toSize = 0);
|
||||
void growBuf(BSSizeType toSize = 0);
|
||||
/**
|
||||
* handles member copying from one ByteStream to another
|
||||
*/
|
||||
@@ -476,9 +477,8 @@ class ByteStream : public Serializeable
|
||||
uint8_t* fBuf; /// the start of the allocated buffer
|
||||
uint8_t* fCurInPtr; // the point in fBuf where data is inserted next
|
||||
uint8_t* fCurOutPtr; // the point in fBuf where data is extracted from next
|
||||
uint32_t fMaxLen; // how big fBuf is currently
|
||||
// Stores `long strings`.
|
||||
std::vector<std::shared_ptr<uint8_t[]>> longStrings;
|
||||
BSSizeType fMaxLen; // how big fBuf is currently
|
||||
std::vector<std::shared_ptr<uint8_t[]>> longStrings; // Stores `long strings`.
|
||||
};
|
||||
|
||||
template <int W, typename T = void>
|
||||
@@ -527,7 +527,7 @@ static const uint8_t BS_BLOB = 9;
|
||||
static const uint8_t BS_SERIALIZABLE = 10;
|
||||
static const uint8_t BS_UUID = 11;
|
||||
|
||||
inline ByteStream::ByteStream(const uint8_t* bp, const uint32_t len) : fBuf(0), fMaxLen(0)
|
||||
inline ByteStream::ByteStream(const uint8_t* bp, const BSSizeType len) : fBuf(0), fMaxLen(0)
|
||||
{
|
||||
load(bp, len);
|
||||
}
|
||||
@@ -544,15 +544,15 @@ inline uint8_t* ByteStream::buf()
|
||||
{
|
||||
return fCurOutPtr;
|
||||
}
|
||||
inline uint32_t ByteStream::length() const
|
||||
inline BSSizeType ByteStream::length() const
|
||||
{
|
||||
return (uint32_t)(fCurInPtr - fCurOutPtr);
|
||||
return static_cast<BSSizeType>(fCurInPtr - fCurOutPtr);
|
||||
}
|
||||
inline bool ByteStream::empty() const
|
||||
{
|
||||
return (length() == 0);
|
||||
}
|
||||
inline uint32_t ByteStream::lengthWithHdrOverhead() const
|
||||
inline BSSizeType ByteStream::lengthWithHdrOverhead() const
|
||||
{
|
||||
return (length() + ISSOverhead);
|
||||
}
|
||||
@@ -570,7 +570,7 @@ inline void ByteStream::rewind()
|
||||
{
|
||||
fCurOutPtr = fBuf + ISSOverhead;
|
||||
}
|
||||
inline void ByteStream::advance(uint32_t adv)
|
||||
inline void ByteStream::advance(BSSizeType adv)
|
||||
{
|
||||
// fCurOutPtr is always >= fBuf, so fCurOutPtr - fBuf is >= 0, and this difference is always <= 32 bits
|
||||
// there is an edge condition not detected here: if fCurOutPtr - fBuf is nearly 4GB and you try to
|
||||
@@ -619,7 +619,7 @@ inline ByteStream& ByteStream::operator=(const SBS& rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint32_t ByteStream::getBufferSize() const
|
||||
inline BSSizeType ByteStream::getBufferSize() const
|
||||
{
|
||||
return fMaxLen;
|
||||
}
|
||||
@@ -738,12 +738,6 @@ void deserializeSet(ByteStream& bs, std::set<T>& s)
|
||||
s.insert(tmp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
template<>
|
||||
struct ByteStream::_ByteStreamType<1, ByteStream::byte>>
|
||||
{
|
||||
typedef ByteStream::byte type;
|
||||
}*/
|
||||
|
||||
} // namespace messageqcpp
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*
|
||||
*
|
||||
***********************************************************************/
|
||||
#include "bytestream.h"
|
||||
#include "mcsconfig.h"
|
||||
|
||||
#include <stdexcept>
|
||||
@@ -117,7 +118,7 @@ const SBS CompressedInetStreamSocket::read(const struct timespec* timeout, bool*
|
||||
|
||||
void CompressedInetStreamSocket::write(const ByteStream& msg, Stats* stats)
|
||||
{
|
||||
size_t len = msg.length();
|
||||
BSSizeType len = msg.length();
|
||||
|
||||
if (useCompression && (len > 512))
|
||||
{
|
||||
@@ -126,6 +127,9 @@ void CompressedInetStreamSocket::write(const ByteStream& msg, Stats* stats)
|
||||
|
||||
alg->compress((char*)msg.buf(), len, (char*)smsg.getInputPtr() + HEADER_SIZE, &outLen);
|
||||
// Save original len.
|
||||
// !!!
|
||||
// !!! Reducing BS size type from 64bit down to 32 and potentially loosing data.
|
||||
// !!!
|
||||
*(uint32_t*)smsg.getInputPtr() = len;
|
||||
smsg.advanceInputPtr(outLen + HEADER_SIZE);
|
||||
|
||||
|
||||
@@ -572,6 +572,9 @@ void InetStreamSocket::write(SBS msg, Stats* stats)
|
||||
|
||||
void InetStreamSocket::do_write(const ByteStream& msg, uint32_t whichMagic, Stats* stats) const
|
||||
{
|
||||
// !!!
|
||||
// !!! Reducing BS size type from 64bit down to 32 and potentially loosing data.
|
||||
// !!!
|
||||
uint32_t msglen = msg.length();
|
||||
uint32_t magic = whichMagic;
|
||||
uint32_t* realBuf;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <iterator>
|
||||
using namespace std;
|
||||
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "bytestream.h"
|
||||
@@ -49,8 +48,6 @@ namespace rowgroup
|
||||
{
|
||||
using cscType = execplan::CalpontSystemCatalog::ColDataType;
|
||||
|
||||
|
||||
|
||||
StringStore::~StringStore()
|
||||
{
|
||||
#if 0
|
||||
@@ -302,47 +299,27 @@ void UserDataStore::deserialize(ByteStream& bs)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RGData::RGData(const RowGroup& rg, uint32_t rowCount)
|
||||
{
|
||||
// cout << "rgdata++ = " << __sync_add_and_fetch(&rgDataCount, 1) << endl;
|
||||
rowData.reset(new uint8_t[rg.getDataSize(rowCount)]);
|
||||
RGDataSizeType s = rg.getDataSize(rowCount);
|
||||
rowData.reset(new uint8_t[s]);
|
||||
|
||||
if (rg.usesStringTable() && rowCount > 0)
|
||||
strings.reset(new StringStore());
|
||||
|
||||
userDataStore.reset();
|
||||
|
||||
|
||||
#ifdef VALGRIND
|
||||
/* In a PM-join, we can serialize entire tables; not every value has been
|
||||
* filled in yet. Need to look into that. Valgrind complains that
|
||||
* those bytes are uninitialized, this suppresses that error.
|
||||
*/
|
||||
memset(rowData.get(), 0, rg.getDataSize(rowCount)); // XXXPAT: make valgrind happy temporarily
|
||||
#endif
|
||||
memset(rowData.get(), 0, rg.getDataSize(rowCount)); // XXXPAT: make valgrind happy temporarily
|
||||
columnCount = rg.getColumnCount();
|
||||
rowSize = rg.getRowSize();
|
||||
}
|
||||
|
||||
RGData::RGData(const RowGroup& rg)
|
||||
{
|
||||
// cout << "rgdata++ = " << __sync_add_and_fetch(&rgDataCount, 1) << endl;
|
||||
rowData.reset(new uint8_t[rg.getMaxDataSize()]);
|
||||
|
||||
if (rg.usesStringTable())
|
||||
strings.reset(new StringStore());
|
||||
|
||||
userDataStore.reset();
|
||||
|
||||
#ifdef VALGRIND
|
||||
/* In a PM-join, we can serialize entire tables; not every value has been
|
||||
* filled in yet. Need to look into that. Valgrind complains that
|
||||
* those bytes are uninitialized, this suppresses that error.
|
||||
*/
|
||||
memset(rowData.get(), 0, rg.getMaxDataSize());
|
||||
#endif
|
||||
columnCount = rg.getColumnCount();
|
||||
rowSize = rg.getRowSize();
|
||||
}
|
||||
@@ -356,14 +333,6 @@ void RGData::reinit(const RowGroup& rg, uint32_t rowCount)
|
||||
strings.reset(new StringStore());
|
||||
else
|
||||
strings.reset();
|
||||
|
||||
#ifdef VALGRIND
|
||||
/* In a PM-join, we can serialize entire tables; not every value has been
|
||||
* filled in yet. Need to look into that. Valgrind complains that
|
||||
* those bytes are uninitialized, this suppresses that error.
|
||||
*/
|
||||
memset(rowData.get(), 0, rg.getDataSize(rowCount));
|
||||
#endif
|
||||
columnCount = rg.getColumnCount();
|
||||
rowSize = rg.getRowSize();
|
||||
}
|
||||
@@ -373,11 +342,11 @@ void RGData::reinit(const RowGroup& rg)
|
||||
reinit(rg, 8192);
|
||||
}
|
||||
|
||||
void RGData::serialize(ByteStream& bs, uint32_t amount) const
|
||||
void RGData::serialize(ByteStream& bs, RGDataSizeType amount) const
|
||||
{
|
||||
// cout << "serializing!\n";
|
||||
bs << (uint32_t)RGDATA_SIG;
|
||||
bs << (uint32_t)amount;
|
||||
bs << amount;
|
||||
bs << columnCount;
|
||||
bs << rowSize;
|
||||
bs.append(rowData.get(), amount);
|
||||
@@ -399,9 +368,10 @@ void RGData::serialize(ByteStream& bs, uint32_t amount) const
|
||||
bs << (uint8_t)0;
|
||||
}
|
||||
|
||||
void RGData::deserialize(ByteStream& bs, uint32_t defAmount)
|
||||
void RGData::deserialize(ByteStream& bs, RGDataSizeType defAmount)
|
||||
{
|
||||
uint32_t amount, sig;
|
||||
uint32_t sig;
|
||||
RGDataSizeType amount;
|
||||
uint8_t* buf;
|
||||
uint8_t tmp8;
|
||||
|
||||
@@ -642,7 +612,7 @@ string Row::toCSV() const
|
||||
|
||||
void Row::setToNull(uint32_t colIndex)
|
||||
{
|
||||
setNullMark(colIndex, true); // mark as null.
|
||||
setNullMark(colIndex, true); // mark as null.
|
||||
switch (types[colIndex])
|
||||
{
|
||||
case CalpontSystemCatalog::TINYINT: data[offsets[colIndex]] = joblist::TINYINTNULL; break;
|
||||
@@ -665,11 +635,11 @@ void Row::setToNull(uint32_t colIndex)
|
||||
*((int32_t*)&data[offsets[colIndex]]) = static_cast<int32_t>(joblist::DATENULL);
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
if (precision[colIndex] != MagicPrecisionForCountAgg)
|
||||
*((uint64_t*)&data[offsets[colIndex]]) = joblist::BIGINTNULL;
|
||||
else // work around for count() in outer join result.
|
||||
*((uint64_t*)&data[offsets[colIndex]]) = 0;
|
||||
case CalpontSystemCatalog::BIGINT:
|
||||
if (precision[colIndex] != MagicPrecisionForCountAgg)
|
||||
*((uint64_t*)&data[offsets[colIndex]]) = joblist::BIGINTNULL;
|
||||
else // work around for count() in outer join result.
|
||||
*((uint64_t*)&data[offsets[colIndex]]) = 0;
|
||||
|
||||
break;
|
||||
|
||||
@@ -680,9 +650,13 @@ void Row::setToNull(uint32_t colIndex)
|
||||
*((long double*)&data[offsets[colIndex]]) = joblist::LONGDOUBLENULL;
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::DATETIME: *((uint64_t*)&data[offsets[colIndex]]) = joblist::DATETIMENULL; break;
|
||||
case CalpontSystemCatalog::DATETIME:
|
||||
*((uint64_t*)&data[offsets[colIndex]]) = joblist::DATETIMENULL;
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::TIMESTAMP: *((uint64_t*)&data[offsets[colIndex]]) = joblist::TIMESTAMPNULL; break;
|
||||
case CalpontSystemCatalog::TIMESTAMP:
|
||||
*((uint64_t*)&data[offsets[colIndex]]) = joblist::TIMESTAMPNULL;
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::TIME: *((uint64_t*)&data[offsets[colIndex]]) = joblist::TIMENULL; break;
|
||||
|
||||
@@ -716,9 +690,7 @@ void Row::setToNull(uint32_t colIndex)
|
||||
case 7:
|
||||
case 8: *((uint64_t*)&data[offsets[colIndex]]) = joblist::CHAR8NULL; break;
|
||||
|
||||
default:
|
||||
setNullMark(colIndex, true);
|
||||
break;
|
||||
default: setNullMark(colIndex, true); break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -751,7 +723,9 @@ void Row::setToNull(uint32_t colIndex)
|
||||
|
||||
case CalpontSystemCatalog::UTINYINT: data[offsets[colIndex]] = joblist::UTINYINTNULL; break;
|
||||
|
||||
case CalpontSystemCatalog::USMALLINT: *((uint16_t*)&data[offsets[colIndex]]) = joblist::USMALLINTNULL; break;
|
||||
case CalpontSystemCatalog::USMALLINT:
|
||||
*((uint16_t*)&data[offsets[colIndex]]) = joblist::USMALLINTNULL;
|
||||
break;
|
||||
|
||||
case CalpontSystemCatalog::UMEDINT:
|
||||
case CalpontSystemCatalog::UINT: *((uint32_t*)&data[offsets[colIndex]]) = joblist::UINTNULL; break;
|
||||
@@ -760,8 +734,8 @@ void Row::setToNull(uint32_t colIndex)
|
||||
|
||||
default:
|
||||
ostringstream os;
|
||||
os << "Row::initToNull(): got bad column type (" << types[colIndex] << "). Width=" << getColumnWidth(colIndex)
|
||||
<< endl;
|
||||
os << "Row::initToNull(): got bad column type (" << types[colIndex]
|
||||
<< "). Width=" << getColumnWidth(colIndex) << endl;
|
||||
os << toString();
|
||||
throw logic_error(os.str());
|
||||
}
|
||||
@@ -870,8 +844,8 @@ bool Row::isNullValue(uint32_t colIndex) const
|
||||
return strings->isNullValue(offset);
|
||||
}
|
||||
|
||||
// if (data[offsets[colIndex]] == 0) // empty string
|
||||
// return true;
|
||||
// if (data[offsets[colIndex]] == 0) // empty string
|
||||
// return true;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
@@ -1126,7 +1100,6 @@ RowGroup::RowGroup(const RowGroup& r)
|
||||
offsets = &stOffsets[0];
|
||||
else if (!useStringTable && !oldOffsets.empty())
|
||||
offsets = &oldOffsets[0];
|
||||
|
||||
}
|
||||
|
||||
RowGroup& RowGroup::operator=(const RowGroup& r)
|
||||
@@ -1241,27 +1214,28 @@ void RowGroup::serializeRGData(ByteStream& bs) const
|
||||
rgData->serialize(bs, getDataSize());
|
||||
}
|
||||
|
||||
uint32_t RowGroup::getDataSize() const
|
||||
RGDataSizeType RowGroup::getDataSize() const
|
||||
{
|
||||
return getDataSize(getRowCount());
|
||||
}
|
||||
|
||||
uint32_t RowGroup::getDataSize(uint64_t n) const
|
||||
RGDataSizeType RowGroup::getDataSize(uint64_t n) const
|
||||
{
|
||||
return headerSize + (n * getRowSize());
|
||||
return headerSize + (n * static_cast<RGDataSizeType>(getRowSize()));
|
||||
}
|
||||
|
||||
uint32_t RowGroup::getMaxDataSize() const
|
||||
RGDataSizeType RowGroup::getMaxDataSize() const
|
||||
{
|
||||
return headerSize + (8192 * getRowSize());
|
||||
return headerSize + (static_cast<RGDataSizeType>(rgCommonSize) * static_cast<RGDataSizeType>(getRowSize()));
|
||||
}
|
||||
|
||||
uint32_t RowGroup::getMaxDataSizeWithStrings() const
|
||||
RGDataSizeType RowGroup::getMaxDataSizeWithStrings() const
|
||||
{
|
||||
return headerSize + (8192 * (oldOffsets[columnCount] + columnCount));
|
||||
return headerSize +
|
||||
(static_cast<RGDataSizeType>(rgCommonSize) * static_cast<RGDataSizeType>(getRowSizeWithStrings()));
|
||||
}
|
||||
|
||||
uint32_t RowGroup::getEmptySize() const
|
||||
RGDataSizeType RowGroup::getEmptySize() const
|
||||
{
|
||||
return headerSize;
|
||||
}
|
||||
@@ -1331,9 +1305,8 @@ string RowGroup::toString(const std::vector<uint64_t>& used) const
|
||||
os << "rowcount = " << getRowCount() << endl;
|
||||
if (!used.empty())
|
||||
{
|
||||
uint64_t cnt =
|
||||
std::accumulate(used.begin(), used.end(), 0ULL,
|
||||
[](uint64_t a, uint64_t bits) { return a + __builtin_popcountll(bits); });
|
||||
uint64_t cnt = std::accumulate(used.begin(), used.end(), 0ULL, [](uint64_t a, uint64_t bits)
|
||||
{ return a + __builtin_popcountll(bits); });
|
||||
os << "sparse row count = " << cnt << endl;
|
||||
}
|
||||
os << "base rid = " << getBaseRid() << endl;
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
namespace rowgroup
|
||||
{
|
||||
const int16_t rgCommonSize = 8192;
|
||||
using RGDataSizeType = uint64_t;
|
||||
|
||||
/*
|
||||
The RowGroup family of classes encapsulate the data moved through the
|
||||
@@ -270,14 +271,14 @@ class RGData
|
||||
|
||||
|
||||
// amount should be the # returned by RowGroup::getDataSize()
|
||||
void serialize(messageqcpp::ByteStream&, uint32_t amount) const;
|
||||
void serialize(messageqcpp::ByteStream&, RGDataSizeType amount) const;
|
||||
|
||||
// the 'hasLengthField' is there b/c PM aggregation (and possibly others) currently sends
|
||||
// inline data with a length field. Once that's converted to string table format, that
|
||||
// option can go away.
|
||||
void deserialize(messageqcpp::ByteStream&, uint32_t amount = 0); // returns the # of bytes read
|
||||
void deserialize(messageqcpp::ByteStream&, RGDataSizeType amount = 0); // returns the # of bytes read
|
||||
|
||||
inline uint64_t getStringTableMemUsage();
|
||||
inline RGDataSizeType getStringTableMemUsage();
|
||||
void clear();
|
||||
void reinit(const RowGroup& rg);
|
||||
void reinit(const RowGroup& rg, uint32_t rowCount);
|
||||
@@ -1499,15 +1500,15 @@ class RowGroup : public messageqcpp::Serializeable
|
||||
uint32_t getDBRoot() const;
|
||||
void setDBRoot(uint32_t);
|
||||
|
||||
uint32_t getDataSize() const;
|
||||
uint32_t getDataSize(uint64_t n) const;
|
||||
uint32_t getMaxDataSize() const;
|
||||
uint32_t getMaxDataSizeWithStrings() const;
|
||||
uint32_t getEmptySize() const;
|
||||
RGDataSizeType getDataSize() const;
|
||||
RGDataSizeType getDataSize(uint64_t n) const;
|
||||
RGDataSizeType getMaxDataSize() const;
|
||||
RGDataSizeType getMaxDataSizeWithStrings() const;
|
||||
RGDataSizeType getEmptySize() const;
|
||||
|
||||
// this returns the size of the row data with the string table
|
||||
inline uint64_t getSizeWithStrings() const;
|
||||
inline uint64_t getSizeWithStrings(uint64_t n) const;
|
||||
inline RGDataSizeType getSizeWithStrings() const;
|
||||
inline RGDataSizeType getSizeWithStrings(uint64_t n) const;
|
||||
|
||||
// sets the row count to 0 and the baseRid to something
|
||||
// effectively initializing whatever chunk of memory
|
||||
@@ -1628,11 +1629,11 @@ class RowGroup : public messageqcpp::Serializeable
|
||||
uint32_t sTableThreshold = 20;
|
||||
std::shared_ptr<bool[]> forceInline;
|
||||
|
||||
static const uint32_t headerSize = 18;
|
||||
static const uint32_t rowCountOffset = 0;
|
||||
static const uint32_t baseRidOffset = 4;
|
||||
static const uint32_t statusOffset = 12;
|
||||
static const uint32_t dbRootOffset = 14;
|
||||
static const uint64_t headerSize = 18;
|
||||
static const uint64_t rowCountOffset = 0;
|
||||
static const uint64_t baseRidOffset = 4;
|
||||
static const uint64_t statusOffset = 12;
|
||||
static const uint64_t dbRootOffset = 14;
|
||||
};
|
||||
|
||||
inline uint64_t convertToRid(const uint32_t& partNum, const uint16_t& segNum, const uint8_t& extentNum,
|
||||
@@ -1778,7 +1779,7 @@ inline uint32_t RowGroup::getRowSizeWithStrings() const
|
||||
return oldOffsets[columnCount] + columnCount;
|
||||
}
|
||||
|
||||
inline uint64_t RowGroup::getSizeWithStrings(uint64_t n) const
|
||||
inline RGDataSizeType RowGroup::getSizeWithStrings(uint64_t n) const
|
||||
{
|
||||
if (strings == nullptr)
|
||||
return getDataSize(n);
|
||||
|
||||
@@ -689,6 +689,7 @@ class RowGroupStorage
|
||||
if (fRGDatas[rgid])
|
||||
{
|
||||
fRowGroupOut->setData(fRGDatas[rgid].get());
|
||||
// An implicit s2u type cast.
|
||||
int64_t memSz = fRowGroupOut->getSizeWithStrings(fMaxRows);
|
||||
if (!fMM->acquire(memSz))
|
||||
{
|
||||
@@ -965,7 +966,7 @@ class RowGroupStorage
|
||||
|
||||
while (rgid >= fRGDatas.size())
|
||||
{
|
||||
int64_t memSz = fRowGroupOut->getSizeWithStrings(fMaxRows);
|
||||
auto memSz = fRowGroupOut->getSizeWithStrings(fMaxRows);
|
||||
if (!fMM->acquire(memSz))
|
||||
{
|
||||
throw logging::IDBExcept(
|
||||
|
||||
@@ -753,7 +753,7 @@ void IdbOrderBy::initialize(const RowGroup& rg)
|
||||
// initialize rows
|
||||
IdbCompare::initialize(rg);
|
||||
|
||||
uint64_t newSize = rg.getSizeWithStrings(fRowsPerRG);
|
||||
auto newSize = rg.getSizeWithStrings(fRowsPerRG);
|
||||
if (fRm && !fRm->getMemory(newSize, fSessionMemLimit))
|
||||
{
|
||||
cerr << IDBErrorInfo::instance()->errorMsg(fErrorCode) << " @" << __FILE__ << ":" << __LINE__;
|
||||
|
||||
Reference in New Issue
Block a user