|
@@ -229,7 +229,8 @@ public:
|
|
|
class CSpillableStreamBase : public CSpillable
|
|
|
{
|
|
|
protected:
|
|
|
- bool preserveNulls, ownsRows;
|
|
|
+ bool ownsRows;
|
|
|
+ EmptyRowSemantics emptyRowSemantics;
|
|
|
unsigned spillCompInfo;
|
|
|
CThorSpillableRowArray rows;
|
|
|
OwnedIFile spillFile;
|
|
@@ -252,13 +253,13 @@ protected:
|
|
|
return true;
|
|
|
}
|
|
|
public:
|
|
|
- CSpillableStreamBase(CActivityBase &_activity, CThorSpillableRowArray &inRows, IThorRowInterfaces *_rowIf, bool _preserveNulls, unsigned _spillPriority)
|
|
|
- : CSpillable(_activity, _rowIf, _spillPriority), rows(_activity), preserveNulls(_preserveNulls)
|
|
|
+ CSpillableStreamBase(CActivityBase &_activity, CThorSpillableRowArray &inRows, IThorRowInterfaces *_rowIf, EmptyRowSemantics _emptyRowSemantics, unsigned _spillPriority)
|
|
|
+ : CSpillable(_activity, _rowIf, _spillPriority), rows(_activity), emptyRowSemantics(_emptyRowSemantics)
|
|
|
{
|
|
|
assertex(inRows.isFlushed());
|
|
|
ownsRows = false;
|
|
|
spillCompInfo = 0x0;
|
|
|
- rows.setup(rowIf, _preserveNulls);
|
|
|
+ rows.setup(rowIf, emptyRowSemantics);
|
|
|
rows.swap(inRows);
|
|
|
}
|
|
|
~CSpillableStreamBase()
|
|
@@ -337,9 +338,7 @@ class CSharedSpillableRowSet : public CSpillableStreamBase
|
|
|
{
|
|
|
block.clearCB = true;
|
|
|
assertex(((offset_t)-1) != outputOffset);
|
|
|
- unsigned rwFlags = DEFAULT_RWFLAGS;
|
|
|
- if (owner->preserveNulls)
|
|
|
- rwFlags |= rw_grouped;
|
|
|
+ unsigned rwFlags = DEFAULT_RWFLAGS | mapESRToRWFlags(owner->emptyRowSemantics);
|
|
|
spillStream.setown(::createRowStreamEx(owner->spillFile, owner->rowIf, outputOffset, (offset_t)-1, (unsigned __int64)-1, rwFlags));
|
|
|
owner->rows.unregisterWriteCallback(*this); // no longer needed
|
|
|
ret = spillStream->nextRow();
|
|
@@ -358,7 +357,7 @@ class CSharedSpillableRowSet : public CSpillableStreamBase
|
|
|
}
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
- if (!owner->preserveNulls)
|
|
|
+ if (ers_forbidden == owner->emptyRowSemantics)
|
|
|
eos = true;
|
|
|
}
|
|
|
return nullptr;
|
|
@@ -380,8 +379,8 @@ class CSharedSpillableRowSet : public CSpillableStreamBase
|
|
|
};
|
|
|
|
|
|
public:
|
|
|
- CSharedSpillableRowSet(CActivityBase &_activity, CThorSpillableRowArray &inRows, IThorRowInterfaces *_rowIf, bool _preserveNulls, unsigned _spillPriority)
|
|
|
- : CSpillableStreamBase(_activity, inRows, _rowIf, _preserveNulls, _spillPriority)
|
|
|
+ CSharedSpillableRowSet(CActivityBase &_activity, CThorSpillableRowArray &inRows, IThorRowInterfaces *_rowIf, EmptyRowSemantics _emptyRowSemantics, unsigned _spillPriority)
|
|
|
+ : CSpillableStreamBase(_activity, inRows, _rowIf, _emptyRowSemantics, _spillPriority)
|
|
|
{
|
|
|
activateSpillingCallback();
|
|
|
}
|
|
@@ -391,9 +390,7 @@ public:
|
|
|
if (spillFile) // already spilled?
|
|
|
{
|
|
|
block.clearCB = true;
|
|
|
- unsigned rwFlags = DEFAULT_RWFLAGS;
|
|
|
- if (preserveNulls)
|
|
|
- rwFlags |= rw_grouped;
|
|
|
+ unsigned rwFlags = DEFAULT_RWFLAGS | mapESRToRWFlags(emptyRowSemantics);
|
|
|
return ::createRowStream(spillFile, rowIf, rwFlags);
|
|
|
}
|
|
|
rowidx_t toRead = rows.numCommitted();
|
|
@@ -414,8 +411,8 @@ class CSpillableStream : public CSpillableStreamBase, implements IRowStream
|
|
|
public:
|
|
|
IMPLEMENT_IINTERFACE_USING(CSpillableStreamBase);
|
|
|
|
|
|
- CSpillableStream(CActivityBase &_activity, CThorSpillableRowArray &inRows, IThorRowInterfaces *_rowIf, bool _preserveNulls, unsigned _spillPriority, unsigned _spillCompInfo)
|
|
|
- : CSpillableStreamBase(_activity, inRows, _rowIf, _preserveNulls, _spillPriority)
|
|
|
+ CSpillableStream(CActivityBase &_activity, CThorSpillableRowArray &inRows, IThorRowInterfaces *_rowIf, EmptyRowSemantics _emptyRowSemantics, unsigned _spillPriority, unsigned _spillCompInfo)
|
|
|
+ : CSpillableStreamBase(_activity, inRows, _rowIf, _emptyRowSemantics, _spillPriority)
|
|
|
{
|
|
|
spillCompInfo = _spillCompInfo;
|
|
|
pos = numReadRows = 0;
|
|
@@ -449,8 +446,7 @@ public:
|
|
|
rwFlags |= rw_compress;
|
|
|
rwFlags |= spillCompInfo;
|
|
|
}
|
|
|
- if (preserveNulls)
|
|
|
- rwFlags |= rw_grouped;
|
|
|
+ rwFlags |= mapESRToRWFlags(emptyRowSemantics);
|
|
|
spillStream.setown(createRowStream(spillFile, rowIf, rwFlags));
|
|
|
return spillStream->nextRow();
|
|
|
}
|
|
@@ -668,18 +664,15 @@ inline bool CThorExpandingRowArray::_resize(rowidx_t requiredRows, unsigned maxS
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-CThorExpandingRowArray::CThorExpandingRowArray(CActivityBase &_activity)
|
|
|
- : activity(_activity)
|
|
|
+CThorExpandingRowArray::CThorExpandingRowArray(CActivityBase &_activity) : activity(_activity)
|
|
|
{
|
|
|
- initCommon();
|
|
|
- setup(NULL, false, stableSort_none, true);
|
|
|
+ rowManager = activity.queryRowManager();
|
|
|
}
|
|
|
|
|
|
-CThorExpandingRowArray::CThorExpandingRowArray(CActivityBase &_activity, IThorRowInterfaces *_rowIf, bool _allowNulls, StableSortFlag _stableSort, bool _throwOnOom, rowidx_t initialSize)
|
|
|
+CThorExpandingRowArray::CThorExpandingRowArray(CActivityBase &_activity, IThorRowInterfaces *_rowIf, EmptyRowSemantics _emptyRowSemantics, StableSortFlag _stableSort, bool _throwOnOom, rowidx_t initialSize)
|
|
|
: activity(_activity)
|
|
|
{
|
|
|
- initCommon();
|
|
|
- setup(_rowIf, _allowNulls, _stableSort, _throwOnOom);
|
|
|
+ setup(_rowIf, _emptyRowSemantics, _stableSort, _throwOnOom);
|
|
|
if (initialSize)
|
|
|
{
|
|
|
rows = static_cast<const void * *>(rowManager->allocate(initialSize * sizeof(void*), activity.queryContainer().queryId(), defaultMaxSpillCost));
|
|
@@ -697,18 +690,10 @@ CThorExpandingRowArray::~CThorExpandingRowArray()
|
|
|
ReleaseThorRow(stableTable);
|
|
|
}
|
|
|
|
|
|
-void CThorExpandingRowArray::initCommon()
|
|
|
-{
|
|
|
- stableTable = NULL;
|
|
|
- rows = NULL;
|
|
|
- maxRows = 0;
|
|
|
- numRows = 0;
|
|
|
-}
|
|
|
-
|
|
|
-void CThorExpandingRowArray::setup(IThorRowInterfaces *_rowIf, bool _allowNulls, StableSortFlag _stableSort, bool _throwOnOom)
|
|
|
+void CThorExpandingRowArray::setup(IThorRowInterfaces *_rowIf, EmptyRowSemantics _emptyRowSemantics, StableSortFlag _stableSort, bool _throwOnOom)
|
|
|
{
|
|
|
rowIf = _rowIf;
|
|
|
- allowNulls = _allowNulls;
|
|
|
+ emptyRowSemantics = _emptyRowSemantics;
|
|
|
stableSort = _stableSort;
|
|
|
throwOnOom = _throwOnOom;
|
|
|
if (rowIf)
|
|
@@ -784,7 +769,7 @@ void CThorExpandingRowArray::swap(CThorExpandingRowArray &other)
|
|
|
IThorRowInterfaces *otherRowIf = other.rowIf;
|
|
|
const void **otherRows = other.rows;
|
|
|
void **otherStableTable = other.stableTable;
|
|
|
- bool otherAllowNulls = other.allowNulls;
|
|
|
+ EmptyRowSemantics otherEmptyRowSemantics = other.emptyRowSemantics;
|
|
|
StableSortFlag otherStableSort = other.stableSort;
|
|
|
bool otherThrowOnOom = other.throwOnOom;
|
|
|
unsigned otherDefaultMaxSpillCost = other.defaultMaxSpillCost;
|
|
@@ -796,7 +781,7 @@ void CThorExpandingRowArray::swap(CThorExpandingRowArray &other)
|
|
|
other.stableTable = stableTable;
|
|
|
other.maxRows = maxRows;
|
|
|
other.numRows = numRows;
|
|
|
- other.setup(rowIf, allowNulls, stableSort, throwOnOom);
|
|
|
+ other.setup(rowIf, emptyRowSemantics, stableSort, throwOnOom);
|
|
|
other.setDefaultMaxSpillCost(defaultMaxSpillCost);
|
|
|
|
|
|
rowManager = otherRowManager;
|
|
@@ -804,7 +789,7 @@ void CThorExpandingRowArray::swap(CThorExpandingRowArray &other)
|
|
|
stableTable = otherStableTable;
|
|
|
maxRows = otherMaxRows;
|
|
|
numRows = otherNumRows;
|
|
|
- setup(otherRowIf, otherAllowNulls, otherStableSort, otherThrowOnOom);
|
|
|
+ setup(otherRowIf, otherEmptyRowSemantics, otherStableSort, otherThrowOnOom);
|
|
|
setDefaultMaxSpillCost(otherDefaultMaxSpillCost);
|
|
|
}
|
|
|
|
|
@@ -1160,7 +1145,7 @@ void CThorExpandingRowArray::serialize(MemoryBuffer &mb)
|
|
|
{
|
|
|
assertex(serializer);
|
|
|
CMemoryRowSerializer s(mb);
|
|
|
- if (!allowNulls)
|
|
|
+ if (emptyRowSemantics == ers_forbidden)
|
|
|
serialize(s);
|
|
|
else
|
|
|
{
|
|
@@ -1234,7 +1219,7 @@ void CThorExpandingRowArray::deserializeRow(IRowDeserializerSource &in)
|
|
|
|
|
|
void CThorExpandingRowArray::deserialize(size32_t sz, const void *buf)
|
|
|
{
|
|
|
- if (allowNulls)
|
|
|
+ if (emptyRowSemantics != ers_forbidden)
|
|
|
{
|
|
|
ASSERTEX((sz>=sizeof(short))&&(*(unsigned short *)buf==0x7631)); // check for mismatch
|
|
|
buf = (const byte *)buf+sizeof(unsigned short);
|
|
@@ -1243,7 +1228,7 @@ void CThorExpandingRowArray::deserialize(size32_t sz, const void *buf)
|
|
|
CThorStreamDeserializerSource d(sz,buf);
|
|
|
while (!d.eos())
|
|
|
{
|
|
|
- if (allowNulls)
|
|
|
+ if (emptyRowSemantics != ers_forbidden)
|
|
|
{
|
|
|
bool nullrow;
|
|
|
d.read(sizeof(bool),&nullrow);
|
|
@@ -1291,15 +1276,12 @@ void CThorSpillableRowArray::safeUnregisterWriteCallback(IWritePosCallback &cb)
|
|
|
CThorSpillableRowArray::CThorSpillableRowArray(CActivityBase &activity)
|
|
|
: CThorExpandingRowArray(activity)
|
|
|
{
|
|
|
- initCommon();
|
|
|
- commitDelta = CommitStep;
|
|
|
throwOnOom = false;
|
|
|
}
|
|
|
|
|
|
-CThorSpillableRowArray::CThorSpillableRowArray(CActivityBase &activity, IThorRowInterfaces *rowIf, bool allowNulls, StableSortFlag stableSort, rowidx_t initialSize, size32_t _commitDelta)
|
|
|
- : CThorExpandingRowArray(activity, rowIf, false, stableSort, false, initialSize), commitDelta(_commitDelta)
|
|
|
+CThorSpillableRowArray::CThorSpillableRowArray(CActivityBase &activity, IThorRowInterfaces *rowIf, EmptyRowSemantics emptyRowSemantics, StableSortFlag stableSort, rowidx_t initialSize, size32_t _commitDelta)
|
|
|
+ : CThorExpandingRowArray(activity, rowIf, ers_forbidden, stableSort, false, initialSize), commitDelta(_commitDelta)
|
|
|
{
|
|
|
- initCommon();
|
|
|
}
|
|
|
|
|
|
CThorSpillableRowArray::~CThorSpillableRowArray()
|
|
@@ -1307,12 +1289,6 @@ CThorSpillableRowArray::~CThorSpillableRowArray()
|
|
|
clearRows();
|
|
|
}
|
|
|
|
|
|
-void CThorSpillableRowArray::initCommon()
|
|
|
-{
|
|
|
- commitRows = 0;
|
|
|
- firstRow = 0;
|
|
|
-}
|
|
|
-
|
|
|
void CThorSpillableRowArray::clearRows()
|
|
|
{
|
|
|
roxiemem::ReleaseRoxieRowRange(rows, firstRow, numRows);
|
|
@@ -1361,7 +1337,7 @@ rowidx_t CThorSpillableRowArray::save(IFile &iFile, unsigned _spillCompInfo, boo
|
|
|
rowidx_t n = numCommitted();
|
|
|
if (0 == n)
|
|
|
return 0;
|
|
|
- ActPrintLog(&activity, "%s: CThorSpillableRowArray::save (skipNulls=%s, allowNulls=%s) max rows = %" RIPF "u", tracingPrefix, boolToStr(skipNulls), boolToStr(allowNulls), n);
|
|
|
+ ActPrintLog(&activity, "%s: CThorSpillableRowArray::save (skipNulls=%s, emptyRowSemantics=%u) max rows = %" RIPF "u", tracingPrefix, boolToStr(skipNulls), emptyRowSemantics, n);
|
|
|
|
|
|
if (_spillCompInfo)
|
|
|
assertex(0 == writeCallbacks.ordinality()); // incompatible
|
|
@@ -1372,8 +1348,7 @@ rowidx_t CThorSpillableRowArray::save(IFile &iFile, unsigned _spillCompInfo, boo
|
|
|
rwFlags |= rw_compress;
|
|
|
rwFlags |= _spillCompInfo;
|
|
|
}
|
|
|
- if (allowNulls)
|
|
|
- rwFlags |= rw_grouped;
|
|
|
+ rwFlags |= mapESRToRWFlags(emptyRowSemantics);
|
|
|
|
|
|
// NB: This is always called within a CThorArrayLockBlock, as such no writebacks are added or updating
|
|
|
rowidx_t nextCBI = RCIDXMAX; // indicates none
|
|
@@ -1420,7 +1395,7 @@ rowidx_t CThorSpillableRowArray::save(IFile &iFile, unsigned _spillCompInfo, boo
|
|
|
}
|
|
|
else if (!skipNulls)
|
|
|
{
|
|
|
- assertex(allowNulls);
|
|
|
+ assertex(emptyRowSemantics != ers_forbidden);
|
|
|
writer->putRow(NULL);
|
|
|
}
|
|
|
++i;
|
|
@@ -1589,7 +1564,7 @@ void CThorSpillableRowArray::transferRowsCopy(const void **outRows, bool takeOwn
|
|
|
IRowStream *CThorSpillableRowArray::createRowStream(unsigned spillPriority, unsigned spillCompInfo)
|
|
|
{
|
|
|
assertex(rowIf);
|
|
|
- return new CSpillableStream(activity, *this, rowIf, allowNulls, spillPriority, spillCompInfo);
|
|
|
+ return new CSpillableStream(activity, *this, rowIf, emptyRowSemantics, spillPriority, spillCompInfo);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1608,7 +1583,7 @@ protected:
|
|
|
offset_t sizeSpill;
|
|
|
ICompare *iCompare;
|
|
|
StableSortFlag stableSort;
|
|
|
- bool preserveGrouping;
|
|
|
+ EmptyRowSemantics emptyRowSemantics = ers_forbidden;
|
|
|
CriticalSection readerLock;
|
|
|
Owned<CSharedSpillableRowSet> spillableRowSet;
|
|
|
unsigned options;
|
|
@@ -1646,10 +1621,10 @@ protected:
|
|
|
spillCycles += spillTimer.elapsedCycles();
|
|
|
return true;
|
|
|
}
|
|
|
- void setPreserveGrouping(bool _preserveGrouping)
|
|
|
+ void setEmptyRowSemantics(EmptyRowSemantics _emptyRowSemantics)
|
|
|
{
|
|
|
- preserveGrouping = _preserveGrouping;
|
|
|
- spillableRows.setAllowNulls(preserveGrouping);
|
|
|
+ emptyRowSemantics = _emptyRowSemantics;
|
|
|
+ spillableRows.setEmptyRowSemantics(emptyRowSemantics);
|
|
|
}
|
|
|
bool flush()
|
|
|
{
|
|
@@ -1734,8 +1709,7 @@ protected:
|
|
|
rwFlags |= rw_compress;
|
|
|
rwFlags |= spillCompInfo;
|
|
|
}
|
|
|
- if (preserveGrouping)
|
|
|
- rwFlags |= rw_grouped;
|
|
|
+ rwFlags |= mapESRToRWFlags(emptyRowSemantics);
|
|
|
IArrayOf<IRowStream> instrms;
|
|
|
ForEachItemIn(f, spillFiles)
|
|
|
{
|
|
@@ -1778,7 +1752,7 @@ protected:
|
|
|
instrms.append(*spillableRows.createRowStream(spillPriority, spillCompInfo)); // NB: stream will take ownership of rows in spillableRows
|
|
|
else
|
|
|
{
|
|
|
- spillableRowSet.setown(new CSharedSpillableRowSet(activity, spillableRows, rowIf, preserveGrouping, spillPriority));
|
|
|
+ spillableRowSet.setown(new CSharedSpillableRowSet(activity, spillableRows, rowIf, emptyRowSemantics, spillPriority));
|
|
|
instrms.append(*spillableRowSet->createRowStream());
|
|
|
}
|
|
|
}
|
|
@@ -1815,7 +1789,6 @@ public:
|
|
|
iCompare(_iCompare), stableSort(_stableSort), diskMemMix(_diskMemMix),
|
|
|
spillableRows(_activity)
|
|
|
{
|
|
|
- preserveGrouping = false;
|
|
|
totalRows = 0;
|
|
|
overflowCount = outStreams = 0;
|
|
|
sizeSpill = 0;
|
|
@@ -1825,7 +1798,7 @@ public:
|
|
|
activateSpillingCallback();
|
|
|
maxCores = activity.queryMaxCores();
|
|
|
options = 0;
|
|
|
- spillableRows.setup(rowIf, false, stableSort);
|
|
|
+ spillableRows.setup(rowIf, ers_forbidden, stableSort);
|
|
|
if (activity.getOptBool(THOROPT_COMPRESS_SPILLS, true))
|
|
|
{
|
|
|
StringBuffer compType;
|
|
@@ -1914,7 +1887,7 @@ public:
|
|
|
mmRegistered = false;
|
|
|
activity.queryRowManager()->removeRowBuffer(this);
|
|
|
}
|
|
|
- spillableRows.setup(rowIf, false, stableSort);
|
|
|
+ spillableRows.setup(rowIf, ers_forbidden, stableSort);
|
|
|
}
|
|
|
virtual void resize(rowidx_t max)
|
|
|
{
|
|
@@ -1967,7 +1940,7 @@ class CThorRowLoader : public CThorRowCollectorBase, implements IThorRowLoader
|
|
|
if (doReset)
|
|
|
reset();
|
|
|
activateSpillingCallback();
|
|
|
- setPreserveGrouping(trl_preserveGrouping == grouping);
|
|
|
+ setEmptyRowSemantics(trl_preserveGrouping == grouping ? ers_eogonly : ers_forbidden);
|
|
|
while (!abort)
|
|
|
{
|
|
|
const void *next = in->nextRow();
|
|
@@ -2050,10 +2023,10 @@ public:
|
|
|
{
|
|
|
}
|
|
|
// IThorRowCollectorCommon
|
|
|
- virtual void setPreserveGrouping(bool tf)
|
|
|
+ virtual void setEmptyRowSemantics(EmptyRowSemantics emptyGroupSemantics)
|
|
|
{
|
|
|
- assertex(!iCompare || !tf); // can't sort if group preserving
|
|
|
- CThorRowCollectorBase::setPreserveGrouping(tf);
|
|
|
+ assertex(!iCompare || (ers_forbidden == emptyGroupSemantics)); // can't sort if preserving end of groups or nulls
|
|
|
+ CThorRowCollectorBase::setEmptyRowSemantics(emptyGroupSemantics);
|
|
|
}
|
|
|
virtual rowcount_t numRows() const { return CThorRowCollectorBase::numRows(); }
|
|
|
virtual unsigned numOverflows() const { return CThorRowCollectorBase::numOverflows(); }
|
|
@@ -2118,10 +2091,10 @@ public:
|
|
|
virtual bool shrink(StringBuffer *traceInfo) { return CThorRowCollectorBase::shrink(traceInfo); }
|
|
|
};
|
|
|
|
|
|
-IThorRowCollector *createThorRowCollector(CActivityBase &activity, IThorRowInterfaces *rowIf, ICompare *iCompare, StableSortFlag stableSort, RowCollectorSpillFlags diskMemMix, unsigned spillPriority, bool preserveGrouping)
|
|
|
+IThorRowCollector *createThorRowCollector(CActivityBase &activity, IThorRowInterfaces *rowIf, ICompare *iCompare, StableSortFlag stableSort, RowCollectorSpillFlags diskMemMix, unsigned spillPriority, EmptyRowSemantics emptyRowSemantics)
|
|
|
{
|
|
|
Owned<IThorRowCollector> collector = new CThorRowCollector(activity, rowIf, iCompare, stableSort, diskMemMix, spillPriority);
|
|
|
- collector->setPreserveGrouping(preserveGrouping);
|
|
|
+ collector->setEmptyRowSemantics(emptyRowSemantics);
|
|
|
return collector.getClear();
|
|
|
}
|
|
|
|