From 29f113a93d2aef963e47b2b64c4cc22a9bcdd712 Mon Sep 17 00:00:00 2001 From: Max Neunhoeffer Date: Tue, 29 Jul 2014 12:18:03 +0200 Subject: [PATCH] New draft for AqlItem, AqlValue, AqlExpression. --- arangod/Aql/ExecutionBlock.h | 3 +- arangod/Aql/Types.h | 167 ++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 55 deletions(-) diff --git a/arangod/Aql/ExecutionBlock.h b/arangod/Aql/ExecutionBlock.h index a0dad193e2..3a43d96d30 100644 --- a/arangod/Aql/ExecutionBlock.h +++ b/arangod/Aql/ExecutionBlock.h @@ -171,7 +171,8 @@ namespace triagens { for (size_t i = 0; i < n; ++i) { TRI_shaped_json_t shaped; TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, docs[i]->getDataPtr()); - triagens::basics::Json json(TRI_UNKNOWN_MEM_ZONE, TRI_JsonShapedJson(shaper, &shaped)); + triagens::basics::Json* json + = new triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, TRI_JsonShapedJson(shaper, &shaped)); _buffer.push_back(new AqlValue(json)); } diff --git a/arangod/Aql/Types.h b/arangod/Aql/Types.h index d87f356b17..fb57e5bbb1 100644 --- a/arangod/Aql/Types.h +++ b/arangod/Aql/Types.h @@ -37,88 +37,147 @@ namespace triagens { namespace aql { // ----------------------------------------------------------------------------- -// --SECTION-- AqlValues +// --SECTION-- AqlDoc // ----------------------------------------------------------------------------- -//////////////////////////////////////////////////////////////////////////////// -/// @brief struct AqlValue, used to pipe documents through executions -/// the execution engine keeps one AqlValue struct for each document -/// that is piped through the engine. Note that the document can exist -/// in one of two formats throughout its lifetime in the engine. -/// When it resides originally in the WAl or a datafile, it stays -/// there unchanged and we only store a (pointer to) a copy of the -/// TRI_doc_mptr_t struct. Sometimes, when it is modified (or created -/// on the fly anyway), we keep the document as a TRI_json_t, wrapped -/// by a Json struct. That is, the following struct has the following -/// invariant: -/// Either the whole struct is empty and thus _json is empty and _mptr -/// is a nullptr. Otherwise, either _json is empty and _mptr is not a -/// nullptr, or _json is non-empty and _mptr is anullptr. -/// Additionally, the struct contains another TRI_json_t holding -/// the current state of the LET variables (and possibly some other -/// computations). This is the _vars attribute. -/// Note that both Json subobjects are constructed as AUTOFREE. -//////////////////////////////////////////////////////////////////////////////// + + struct AqlItem; struct AqlValue { - triagens::basics::Json _json; - TRI_doc_mptr_t* _mptr; - triagens::basics::Json _vars; -//////////////////////////////////////////////////////////////////////////////// -/// @brief convenience constructors -//////////////////////////////////////////////////////////////////////////////// + enum AqlValueType { + JSON, + DOCVEC, + RANGE + }; - AqlValue () - : _json(), _mptr(nullptr), _vars() { + struct Range { + int64_t _low; + int64_t _high; + Range(int64_t low, int64_t high) : _low(low), _high(high) {} + }; + + union { + triagens::basics::Json* _json; + std::vector* _vector; + Range _range; + }; + + AqlValueType _type; + + AqlValue (triagens::basics::Json* json) + : _json(json), _type(JSON) { } - AqlValue (TRI_doc_mptr_t* mptr) - : _json(), _mptr(mptr), _vars() { + AqlValue (std::vector* vector) + : _vector(vector), _type(DOCVEC) { } - AqlValue (triagens::basics::Json json) - : _json(json), _mptr(nullptr), _vars() { + AqlValue (int64_t low, int64_t high) + : _range(low, high), _type(RANGE) { + } + + ~AqlValue () { + switch (_type) { + case JSON: + delete _json; + break; + case DOCVEC: + delete _vector; + break; + case RANGE: + break; + } + } + + std::string toString () { + switch (_type) { + case JSON: + return _json->toString(); + case DOCVEC: + return "I am a DOCVEC."; + case RANGE: + std::stringstream s; + s << "I am a range: " << _range._low << " .. " << _range._high; + return s.str(); + } + } + + }; + + struct AqlItem { + AqlItem* _outer; + int32_t _refcount; + int32_t _nrvars; + AqlValue** _vars; + + AqlItem (int nrvars) + : _outer(nullptr), _refcount(1), _nrvars(nrvars) { + if (nrvars > 0) { + _vars = new AqlValue* [nrvars]; + } + else { + _vars = nullptr; + } + } + + AqlItem (AqlItem* outer, int nrvars) + : _outer(outer), _refcount(1), _nrvars(nrvars) { + outer->_refcount++; + if (nrvars > 0) { + _vars = new AqlValue* [nrvars]; + for (int i = 0; i < nrvars; i++) { + _vars[i] = nullptr; + } + } + else { + _vars = nullptr; + } } //////////////////////////////////////////////////////////////////////////////// /// @brief destructor //////////////////////////////////////////////////////////////////////////////// - ~AqlValue () { - } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief return a string representation of the value -//////////////////////////////////////////////////////////////////////////////// - - std::string toString () const { - std::string out; - if (! _json.isEmpty()) { - out += _json.toString(); + ~AqlItem () { + if (_outer != nullptr) { + _outer->_refcount--; + if (_outer->_refcount == 0) { + delete _outer; + } + _outer = nullptr; } - else if (_mptr != nullptr) { - out.append("got a master pointer"); + if (_vars != nullptr) { + for (int i = 0; i < _nrvars; i++) { + delete _vars[i]; + } + delete[] _vars; } - - if (! _vars.isEmpty()) { - out += _vars.toString(); - } - - return out; } //////////////////////////////////////////////////////////////////////////////// /// @brief getValue, get the current value of a variable or attribute //////////////////////////////////////////////////////////////////////////////// - triagens::basics::Json getValue (std::string name); + AqlValue* getValue (int up, int index) { + AqlItem* p = this; + for (int i = 0; i < up; i++) { + p = p->_outer; + } + return p->_vars[index]; + } //////////////////////////////////////////////////////////////////////////////// /// @brief setValue, set the current value of a variable or attribute //////////////////////////////////////////////////////////////////////////////// - void setValue (std::string name, triagens::basics::Json json); + void setValue (int up, int index, AqlValue* zeug) { + AqlItem* p = this; + for (int i = 0; i < up; i++) { + p = p->_outer; + } + p->_vars[index] = zeug; + } }; @@ -173,7 +232,7 @@ namespace triagens { /// @brief execute the expression //////////////////////////////////////////////////////////////////////////////// - triagens::basics::Json execute (AqlValue* aqldoc); + AqlValue* execute (AqlItem* aqldoc); //////////////////////////////////////////////////////////////////////////////// /// @brief private members