//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany /// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// /// @author Kaveh Vahedipour //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_CONSENSUS_NODE_H #define ARANGOD_CONSENSUS_NODE_H 1 #include "AgencyCommon.h" #include "Basics/Mutex.h" #include "Basics/MutexLocker.h" #include "Basics/Thread.h" #include "Basics/ConditionVariable.h" #include #include #include #include #include #include namespace arangodb { namespace consensus { enum NodeType {NODE, LEAF}; enum Operation {SET, INCREMENT, DECREMENT, PUSH, POP, PREPEND, SHIFT, OBSERVE, UNOBSERVE}; using namespace arangodb::velocypack; class StoreException : public std::exception { public: explicit StoreException(std::string const& message) : _message(message) {} virtual char const* what() const noexcept override final { return _message.c_str(); } private: std::string _message; }; enum NODE_EXCEPTION {PATH_NOT_FOUND}; class Node; typedef std::chrono::system_clock::time_point TimePoint; typedef std::multimap> TimeTable; class Store; /// @brief Simple tree implementation class Node { public: // @brief Slash-segemented path typedef std::vector PathType; // @brief Child nodes typedef std::map> Children; /// @brief Construct with name explicit Node (std::string const& name); /// @brief Construct with name and introduce to tree under parent Node (std::string const& name, Node* parent); /// @brief Construct with name and introduce to tree under parent Node (std::string const& name, Store* store); /// @brief Default dtor virtual ~Node (); /// @brief Get name std::string const& name() const; /// @brief Get full path std::string uri() const; /// @brief Apply rhs to this node (deep copy of rhs) Node& operator= (Node const& node); /// @brief Apply value slice to this node Node& operator= (arangodb::velocypack::Slice const&); /// @brief Check equality with slice bool operator== (arangodb::velocypack::Slice const&) const; /// @brief Type of this node (LEAF / NODE) NodeType type() const; /// @brief Get node specified by path vector Node& operator ()(std::vector const& pv); /// @brief Get node specified by path vector Node const& operator ()(std::vector const& pv) const; /// @brief Get node specified by path string Node& operator ()(std::string const& path); /// @brief Get node specified by path string Node const& operator ()(std::string const& path) const; /// @brief Remove child by name bool removeChild (std::string const& key); /// @brief Remove this node and below from tree bool remove(); /// @brief Get root node Node const& root() const; /// @brief Get root node Node& root(); /// @brief Dump to ostream std::ostream& print (std::ostream&) const; /// #brief Get path of this node std::string path (); /// @brief Apply single operation as defined by "op" bool applieOp (arangodb::velocypack::Slice const&); /// @brief Apply single slice bool applies (arangodb::velocypack::Slice const&); /// @brief handle "op" keys in write json template bool handle (arangodb::velocypack::Slice const&); /// @brief Create Builder representing this store void toBuilder (Builder&) const; /// @brief Access children Children& children (); /// @brief Access children Children const& children () const; /// @brief Create slice from value Slice slice() const; /// @brief Get value type ValueType valueType () const; /// @brief Add observer for this node bool addObserver (std::string const&); /// @brief Add observer for this node void notifyObservers (std::string const& origin) const; /// @brief Is this node being observed by url bool observedBy (std::string const& url) const; Store& store(); Store const& store() const; std::string toJson() const; protected: /// @brief Add time to live entry virtual bool addTimeToLive (long millis); /// @brief Remove time to live entry virtual bool removeTimeToLive (); std::string _node_name; /**< @brief my name */ Node* _parent; /**< @brief parent */ Store* _store; /**< @brief Store */ Children _children; /**< @brief child nodes */ TimePoint _ttl; /**< @brief my expiry */ Buffer _value; /**< @brief my value */ }; inline std::ostream& operator<< (std::ostream& o, Node const& n) { return n.print(o); } }} // namespaces #endif