From 5ac060e687fdefdb3b111368e950eb65f111ba1d Mon Sep 17 00:00:00 2001 From: James Date: Wed, 6 Aug 2014 13:36:50 +0200 Subject: [PATCH] adding SortBlock, something not working. --- arangod/Aql/ExecutionBlock.h | 167 +++++++++++++++++++++++++++++++- arangod/Aql/ExecutionEngine.cpp | 5 + arangod/Aql/Types.h | 9 +- 3 files changed, 179 insertions(+), 2 deletions(-) diff --git a/arangod/Aql/ExecutionBlock.h b/arangod/Aql/ExecutionBlock.h index 67bec24bb7..46d34e6f58 100644 --- a/arangod/Aql/ExecutionBlock.h +++ b/arangod/Aql/ExecutionBlock.h @@ -1046,7 +1046,7 @@ namespace triagens { std::unordered_set inVars = _expression->variables(); - for (auto it = inVars.begin(); it != inVars.end(); ++it) { + for (auto it = inVars.begin(); it != inVars.end(); ++it) { _inVars.push_back(*it); auto it2 = _varOverview->varInfo.find((*it)->id); TRI_ASSERT(it2 != _varOverview->varInfo.end()); @@ -1410,6 +1410,171 @@ namespace triagens { }; +// ----------------------------------------------------------------------------- +// --SECTION-- SortBlock +// ----------------------------------------------------------------------------- + + class SortBlock : public ExecutionBlock { + + public: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructor +//////////////////////////////////////////////////////////////////////////////// + + SortBlock (AQL_TRANSACTION_V8* trx, + ExecutionNode const* ep) + : ExecutionBlock(trx, ep) { + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief destructor +//////////////////////////////////////////////////////////////////////////////// + + virtual ~SortBlock () {}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief initialize +//////////////////////////////////////////////////////////////////////////////// + + int initialize () { + int res = ExecutionBlock::initialize(); + if (res != TRI_ERROR_NO_ERROR) { + return res; + } + + auto en = static_cast(getPlanNode()); + + for( auto p: en->_elements){ + //We know that staticAnalysis has been run, so _varOverview is set up + auto it = _varOverview->varInfo.find(p.first->id); + TRI_ASSERT(it != _varOverview->varInfo.end()); + _sortRegisters.push_back(make_pair(it->second.registerId, p.second)); + } + + return TRI_ERROR_NO_ERROR; + } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief execute +//////////////////////////////////////////////////////////////////////////////// + + virtual int execute () { + int res = ExecutionBlock::execute(); + if (res != TRI_ERROR_NO_ERROR) { + return res; + } + // suck all blocks into _buffer + while (getBlock(DefaultBatchSize, DefaultBatchSize)) { + } + + if (_buffer.size()==0){ + _done = true; + return TRI_ERROR_NO_ERROR; + } + + // coords[i][j] is the th row of the th block + std::vector> coords; + + size_t sum = 0; + for (auto block:_buffer){ + sum += block->size(); + } + + coords.reserve(sum); + + // install the coords + size_t count = 0; + + for (auto block:_buffer) { + for (size_t i = 0; i < block->size(); i++) { + coords.push_back(std::make_pair(count, i)); + } + count++; + } + // comparison function + OurLessThan ourLessThan(_buffer, _sortRegisters); + + // sort coords + std::sort(coords.begin(), coords.end(), ourLessThan); + + //copy old points from _buffer into newbuf + std::vector newbuf; + + for (auto x: _buffer) { + newbuf.push_back(x); + } + _buffer.clear(); + + count = 0; + RegisterId nrregs = newbuf.front()->getNrRegs(); + + //install the rearranged values from into <_buffer> + while (count < sum) { + size_t size_next + = (sum - count > DefaultBatchSize ? DefaultBatchSize : sum - count); + AqlItemBlock* next = new AqlItemBlock(size_next, nrregs); + for (size_t i = 0; i < size_next; i++){ + count++; + for (RegisterId j = 0; j < nrregs; j++){ + next->setValue(i, j, + newbuf[coords[count].first]->getValue(coords[count].second, j)); + newbuf[coords[count].first]->eraseValue(coords[count].second, j); + } + } + _buffer.push_back(next); + } + + for ( auto x: newbuf){ + delete x; + } + + return TRI_ERROR_NO_ERROR; + } + + private: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief OurLessThan +//////////////////////////////////////////////////////////////////////////////// + + class OurLessThan { + public: + OurLessThan (std::deque& buffer, + std::vector>& sortRegisters) + : _buffer(buffer), _sortRegisters(sortRegisters) { + } + + bool operator() (std::pair const& a, + std::pair const& b) { + + for(auto reg: _sortRegisters){ + int cmp = _buffer[a.first]->getValue(a.second, reg.first).compare( + _buffer[b.first]->getValue(b.second, reg.first)); + if(cmp == -1) { + return reg.second; + } + else if (cmp == 1) { + return !reg.second; + } + } + + return false; + } + + private: + std::deque& _buffer; + std::vector>& _sortRegisters; + }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief pairs, consisting of variable and sort direction +/// (true = ascending | false = descending) +//////////////////////////////////////////////////////////////////////////////// + + std::vector> _sortRegisters; + + }; // ----------------------------------------------------------------------------- // --SECTION-- LimitBlock diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index fbf85c02f8..3c2b24e1e9 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -111,6 +111,11 @@ struct Instanciator : public ExecutionNode::WalkerWorker { root = eb; break; } + case ExecutionNode::SORT: { + eb = new SortBlock(engine->getTransaction(), + static_cast(en)); + break; + } default: { THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED); } diff --git a/arangod/Aql/Types.h b/arangod/Aql/Types.h index 5b99081edf..acf97063ae 100644 --- a/arangod/Aql/Types.h +++ b/arangod/Aql/Types.h @@ -211,8 +211,15 @@ namespace triagens { return false; } } - }; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 3-way comparison +//////////////////////////////////////////////////////////////////////////////// + int compare (AqlValue const& val){ + return 0; + } + }; } }