diff --git a/3rdParty/velocypack/include/velocypack/Slice.h b/3rdParty/velocypack/include/velocypack/Slice.h index 8426689555..4b6796f39d 100644 --- a/3rdParty/velocypack/include/velocypack/Slice.h +++ b/3rdParty/velocypack/include/velocypack/Slice.h @@ -729,6 +729,7 @@ class Slice { static ValueType const TypeMap[256]; static unsigned int const WidthMap[32]; static unsigned int const FirstSubMap[32]; + static char const* NullStr; }; // a class for keeping Slice allocations in scope diff --git a/3rdParty/velocypack/src/Slice.cpp b/3rdParty/velocypack/src/Slice.cpp index dbf423106c..515531394f 100644 --- a/3rdParty/velocypack/src/Slice.cpp +++ b/3rdParty/velocypack/src/Slice.cpp @@ -213,6 +213,8 @@ unsigned int const Slice::FirstSubMap[32] = { 8, // 0x12, object with unsorted index table 0}; +static char const* NullStr = "0x18"; + // creates a Slice from Json and adds it to a scope Slice Slice::fromJson(SliceScope& scope, std::string const& json, Options const* options) { diff --git a/arangod/Agency/Store.cpp b/arangod/Agency/Store.cpp index 0ddaabcd04..ff8e74a4b4 100644 --- a/arangod/Agency/Store.cpp +++ b/arangod/Agency/Store.cpp @@ -63,7 +63,8 @@ Node::Node (std::string const& name, Node const* parent) : Node::~Node() {} Slice Node::slice() const { - return (_value.size()==0) ? Slice() : Slice(_value.data()); + return (_value.size()==0) ? + Slice("\x018",&Options::Defaults):Slice(_value.data()); } std::string const& Node::name() const {return _name;} @@ -71,7 +72,7 @@ std::string const& Node::name() const {return _name;} Node& Node::operator= (Slice const& slice) { // Assign value (become leaf) _children.clear(); _value.reset(); - _value.append((char const*)slice.begin(), slice.byteSize()); + _value.append(reinterpret_cast(slice.begin()), slice.byteSize()); return *this; } @@ -80,25 +81,45 @@ Node& Node::operator= (Node const& node) { // Assign node _type = node._type; _value = node._value; _children = node._children; + _ttl = node._ttl; return *this; } +/*Node& Node::parent () { + return *_parent; + } + +Node const& Node::parent () const { + return *_parent; + }*/ + +bool Node::remove (std::string const& path) { + std::vector pv = split(path, '/'); + std::string key(pv.back()); + pv.pop_back(); + try { + Node& parent = (*this)(pv); + return parent.removeChild(key); + } catch (StoreException const& e) { + return false; + } +} + +bool Node::removeChild (std::string const& key) { + auto found = _children.find(key); + if (found == _children.end()) + return false; + else + _children.erase(found); + return true; +} + NodeType Node::type() const {return _children.size() ? NODE : LEAF;} Node& Node::operator [](std::string name) { return *_children[name]; } -bool Node::isSingular () const { - if (type() == LEAF) { - return true; - } else if (_children.size()==1) { - return _children.begin()->second->isSingular(); - } else { - return false; - } -} - bool Node::append (std::string const name, std::shared_ptr const node) { if (node != nullptr) { _children[name] = node; @@ -111,13 +132,12 @@ bool Node::append (std::string const name, std::shared_ptr const node) { Node& Node::operator ()(std::vector& pv) { if (pv.size()) { - auto found = _children.find(pv[0]); - if (found == _children.end()) { - _children[pv[0]] = std::make_shared(pv[0], this); - found = _children.find(pv[0]); + std::string const key = pv[0]; + if (_children.find(key) == _children.end()) { + _children[key] = std::make_shared(pv[0], this); } pv.erase(pv.begin()); - return (*found->second)(pv); + return (*_children[key])(pv); } else { return *this; } @@ -125,12 +145,9 @@ Node& Node::operator ()(std::vector& pv) { Node const& Node::operator ()(std::vector& pv) const { if (pv.size()) { - auto found = _children.find(pv[0]); - if (found == _children.end()) { - throw PATH_NOT_FOUND; - } + std::string const key = pv[0]; pv.erase(pv.begin()); - return (*found->second)(pv); + return (*_children.at(key))(pv); } else { return *this; } @@ -164,13 +181,13 @@ bool Node::apply (arangodb::velocypack::Slice const& slice) { auto found = _children.find(key); if (found == _children.end()) { _children[key] = std::make_shared(key, this); - found = _children.find(key); } - found->second->apply(i.value); + _children[key]->apply(i.value); } } else { *this = slice; } +// remove("/g/b"); return true; } @@ -190,7 +207,7 @@ void Node::toBuilder (Builder& builder) const { } } -Store::Store () : Node("root") {} +Store::Store (std::string const& name) : Node(name) {} Store::~Store () {} std::vector Store::apply (query_t const& query) { @@ -227,7 +244,8 @@ Node const& Store::read (std::string const& path) const { return Node::read(path); } -bool Store::check (arangodb::velocypack::Slice const& slice) const{ +bool Store::check (arangodb::velocypack::Slice const& slice) const { + return true; } @@ -272,12 +290,19 @@ bool Store::read (arangodb::velocypack::Slice const& query, Builder& ret) const query_strs.erase (cut,query_strs.end()); // Create response tree - Node node("root"); + Node node("copy"); + const Node rhs(*this); for (auto i = query_strs.begin(); i != query_strs.end(); ++i) { - node(*i) = (*this).read(*i); + try { + rhs(*i); + } catch (StoreException const& e) { + std::cout << e.what(); + continue; + } + node(*i) = rhs(*i); } - - // Assemble builder from node + + // Assemble builder from response tree if (query_strs.size() == 1 && node(*query_strs.begin()).type() == LEAF) { ret.add(node(*query_strs.begin()).slice()); } else { diff --git a/arangod/Agency/Store.h b/arangod/Agency/Store.h index 657d0e6f09..aacbe154d4 100644 --- a/arangod/Agency/Store.h +++ b/arangod/Agency/Store.h @@ -49,6 +49,14 @@ enum NodeType {NODE, LEAF}; using namespace arangodb::velocypack; +class StoreException : public std::exception { +public: + StoreException(std::string const& message) : _message(message) {} + virtual char const* what() const noexcept { return _message.c_str(); } +private: + std::string _message; +}; + enum NODE_EXCEPTION {PATH_NOT_FOUND}; class Node { @@ -80,14 +88,22 @@ public: Node const& operator ()(std::vector& pv) const; - Node const& operator ()(std::string const& path) const; - Node& operator ()(std::string const& path); + Node const& operator ()(std::string const& path) const; + Node const& read (std::string const& path) const; Node& write (std::string const& path); +/* Node& parent (); + + Node const& parent () const;*/ + + bool remove (std::string const& path); + + bool removeChild (std::string const& key); + friend std::ostream& operator<<(std::ostream& os, const Node& n) { Node const* par = n._parent; while (par != 0) { @@ -100,7 +116,7 @@ public: for (auto const& i : n._children) os << *(i.second); } else { - os << n.slice().toJson() << std::endl; + os << ((n.slice().type() == ValueType::None) ? "NONE" : n.slice().toJson()) << std::endl; } return os; } @@ -113,14 +129,15 @@ public: return _value; } - bool isSingular () const; - Slice slice() const; + + protected: Node const* _parent; Children _children; Buffer _value; + std::chrono::system_clock::time_point _ttl; private: NodeType _type; @@ -132,7 +149,7 @@ private: class Store : public Node { // Root node public: - Store (); + Store (std::string const& name = "root"); virtual ~Store (); std::vector apply (query_t const& query);