const void *getResult(const void *firstRow) { IHThorAggregateArg *helper = (IHThorAggregateArg *)baseHelper.get(); unsigned numPartialResults = container.queryJob().querySlaves(); if (1 == numPartialResults) return firstRow; CThorExpandingRowArray partialResults(*this, this, true, stableSort_none, true, numPartialResults); if (hadElement) partialResults.setRow(0, firstRow); --numPartialResults; size32_t sz; while (numPartialResults--) { CMessageBuffer msg; rank_t sender; if (!receiveMsg(msg, RANK_ALL, mpTag, &sender)) return NULL; if (abortSoon) return NULL; msg.read(sz); if (sz) { assertex(NULL == partialResults.query(sender-1)); CThorStreamDeserializerSource mds(sz, msg.readDirect(sz)); RtlDynamicRowBuilder rowBuilder(queryRowAllocator()); size32_t sz = queryRowDeserializer()->deserialize(rowBuilder, mds); partialResults.setRow(sender-1, rowBuilder.finalizeRowClear(sz)); } } RtlDynamicRowBuilder rowBuilder(queryRowAllocator(), false); bool first = true; numPartialResults = container.queryJob().querySlaves(); unsigned p=0; for (;p<numPartialResults; p++) { const void *row = partialResults.query(p); if (row) { if (first) { first = false; sz = cloneRow(rowBuilder, row, queryRowMetaData()); } else sz = helper->mergeAggregate(rowBuilder, row); } } if (first) sz = helper->clearAggregate(rowBuilder); return rowBuilder.finalizeRowClear(sz); }
void RowAggregator::mergeElement(const void * otherElement) { unsigned hash = elementHasher->hash(otherElement); void * match = findElement(hash, otherElement); if (match) { AggregateRowBuilder *rowBuilder = static_cast<AggregateRowBuilder *>(match); totalSize -= rowBuilder->querySize(); size32_t sz = helper.mergeAggregate(*rowBuilder, otherElement); rowBuilder->setSize(sz); totalSize += sz; } else { Owned<AggregateRowBuilder> rowBuilder = new AggregateRowBuilder(rowAllocator, hash); rowBuilder->setSize(cloneRow(*rowBuilder, otherElement, rowAllocator->queryOutputMeta())); addNew(rowBuilder.getClear(), hash); } }
const void *getAggregate(CActivityBase &activity, unsigned partialResults, IRowInterfaces &rowIf, IHThorCompoundAggregateExtra &aggHelper, mptag_t mpTag) { // JCSMORE - pity this isn't common routine with similar one in aggregate, but helper is not common CThorRowArray slaveResults; slaveResults.ensure(partialResults); unsigned _partialResults = partialResults; while (_partialResults--) { CMessageBuffer mb; rank_t sender; if (!activity.receiveMsg(mb, RANK_ALL, mpTag, &sender)) return false; if (activity.queryAbortSoon()) return 0; if (mb.length()) { CThorStreamDeserializerSource ds(mb.length(), mb.readDirect(mb.length())); RtlDynamicRowBuilder rowBuilder(rowIf.queryRowAllocator()); size32_t sz = rowIf.queryRowDeserializer()->deserialize(rowBuilder, ds); slaveResults.setRow(sender-1, rowBuilder.finalizeRowClear(sz)); } } RtlDynamicRowBuilder result(rowIf.queryRowAllocator(), false); size32_t sz; bool first = true; _partialResults = 0; for (;_partialResults<partialResults; _partialResults++) { const void *partialResult = slaveResults.item(_partialResults); if (partialResult) { if (first) { first = false; sz = cloneRow(result, slaveResults.item(_partialResults), rowIf.queryRowMetaData()); } else sz = aggHelper.mergeAggregate(result, partialResult); } } if (first) sz = aggHelper.clearAggregate(result); return result.finalizeRowClear(sz); }