diff --git a/arangod/Cluster/ClusterTraverser.cpp b/arangod/Cluster/ClusterTraverser.cpp new file mode 100644 index 0000000000..929b1c64b5 --- /dev/null +++ b/arangod/Cluster/ClusterTraverser.cpp @@ -0,0 +1,155 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Cluster Traverser +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2014-2015 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 Michael Hackstein +/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany +/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#include "Cluster/ClusterTraverser.h" + +using ClusterTraversalPath = triagens::arango::traverser::ClusterTraversalPath; +using ClusterTraverser = triagens::arango::traverser::ClusterTraverser; + +// ----------------------------------------------------------------------------- +// --SECTION-- class ClusterTraversalPath +// ----------------------------------------------------------------------------- + +triagens::basics::Json* ClusterTraversalPath::pathToJson (Transaction*, + CollectionNameResolver*) const { + return nullptr; +} + +triagens::basics::Json* ClusterTraversalPath::lastEdgeToJson (Transaction*, + CollectionNameResolver*) const { + return nullptr; +} + +triagens::basics::Json* ClusterTraversalPath::lastVertexToJson (Transaction*, + CollectionNameResolver*) const { + return nullptr; +} + +// ----------------------------------------------------------------------------- +// --SECTION-- class ClusterTraverser +// ----------------------------------------------------------------------------- + +std::string ClusterTraverser::VertexGetter::operator() (std::string const& edgeId, + std::string const& vertexId) { + auto it = _edges->find(edgeId); + std::string def = ""; + if (it != _edges->end()) { + std::string from = triagens::basics::JsonHelper::getStringValue(it->second, "_from", def); + if (from != vertexId) { + return from; + } + std::string to = triagens::basics::JsonHelper::getStringValue(it->second, "_to", def); + return to; + } + return def; +} + +void ClusterTraverser::EdgeGetter::operator() (std::string const& startVertex, + std::vector& result, + size_t*& last, + size_t& eColIdx, + bool&) { + // TRI_ASSERT(eColIdx < _edgeCols->size()); + if (last == nullptr) { + TRI_ASSERT(_traverser->_iteratorCache.size() == result.size()); + // We have to request the next level + } + else { + std::stack tmp = _traverser->_iteratorCache.top(); + if (tmp.empty()) { + _traverser->_iteratorCache.pop(); + last = nullptr; + } + else { + std::string next = tmp.top(); + tmp.pop(); + result.push_back(next); + } + } +} +/* +void ClusterTraverser::defineInternalFunctions () { + + auto direction = _opts.direction; + auto edgeCols = _edgeCols; + _getEdge = [&edgeCols, &_iteratorCache] (std::string& startVertex, std::vector& result, size_t*& last, size_t& eColIdx, bool&) { + if (last == nullptr) { + TRI_ASSERT(_iteratorCache.size() == result.size()); + // We have to request the next level + // TODO + } + else { + std::stack tmp = _iteratorCache.top(); + if (tmp.empty()) { + _iteratorCache.pop(); + last = nullptr; + } + else { + result.push_back(tmp.pop()); + } + } + } +} +*/ + +void ClusterTraverser::setStartVertex (VertexId& v) { + // TODO + std::string id = ""; + _enumerator.reset(new triagens::basics::PathEnumerator (_edgeGetter, _vertexGetter, id)); + _done = false; +} + +const triagens::arango::traverser::TraversalPath* ClusterTraverser::next () { + TRI_ASSERT(!_done); + if (_pruneNext) { + _pruneNext = false; + _enumerator->prune(); + } + TRI_ASSERT(!_pruneNext); + const triagens::basics::EnumeratedPath& path = _enumerator->next(); + size_t countEdges = path.edges.size(); + if (countEdges == 0) { + _done = true; + // Done traversing + return nullptr; + } + + std::unique_ptr p(new ClusterTraversalPath(this, path)); + if (_opts.shouldPrunePath(p.get())) { + _enumerator->prune(); + return next(); + } + if (countEdges >= _opts.maxDepth) { + _pruneNext = true; + } + if (countEdges < _opts.minDepth) { + return next(); + } + return p.release(); +} diff --git a/arangod/Cluster/ClusterTraverser.h b/arangod/Cluster/ClusterTraverser.h new file mode 100644 index 0000000000..fd089beac7 --- /dev/null +++ b/arangod/Cluster/ClusterTraverser.h @@ -0,0 +1,157 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief Cluster Traverser +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2014-2015 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 Michael Hackstein +/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany +/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ARANGODB_CLUSTER_CLUSTERTRAVERSER_H +#define ARANGODB_CLUSTER_CLUSTERTRAVERSER_H 1 + +#include "VocBase/Traverser.h" + +namespace triagens { + namespace arango { + namespace traverser { + +// ----------------------------------------------------------------------------- +// --SECTION-- class ClusterTraverser +// ----------------------------------------------------------------------------- + + class ClusterTraverser : public Traverser { + + public: + + ClusterTraverser () + : Traverser(), + _vertexGetter(&_edges), + _edgeGetter(this) { + } + + ~ClusterTraverser () { + } + + void setStartVertex (VertexId& v) override; + + const TraversalPath* next () override; + + private: + +// ----------------------------------------------------------------------------- +// --SECTION-- private classes +// ----------------------------------------------------------------------------- + + class VertexGetter { + + public: + + VertexGetter (std::unordered_map const* edges) + : _edges(edges) { + } + + std::string operator() (std::string const&, std::string const&); + + private: + + std::unordered_map const* _edges; + + }; + + class EdgeGetter { + + public: + + EdgeGetter (ClusterTraverser* traverser) + : _traverser(traverser) { + } + + void operator() (std::string const&, + std::vector&, + size_t*&, + size_t&, + bool&); + + private: + + ClusterTraverser* _traverser; + + + }; + +// ----------------------------------------------------------------------------- +// --SECTION-- private functions +// ----------------------------------------------------------------------------- + + void defineInternalFunctions (); + +// ----------------------------------------------------------------------------- +// --SECTION-- private variables +// ----------------------------------------------------------------------------- + + std::unordered_map _edges; + + std::unordered_map _vertices; + + std::stack> _iteratorCache; + + VertexGetter _vertexGetter; + + EdgeGetter _edgeGetter; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief internal cursor to enumerate the paths of a graph +//////////////////////////////////////////////////////////////////////////////// + + std::unique_ptr> _enumerator; + + }; + + class ClusterTraversalPath : public TraversalPath { + + public: + + ClusterTraversalPath (ClusterTraverser* traverser, const triagens::basics::EnumeratedPath& path) { + } + + triagens::basics::Json* pathToJson (Transaction*, + CollectionNameResolver*) const; + + triagens::basics::Json* lastEdgeToJson (Transaction*, + CollectionNameResolver*) const; + + triagens::basics::Json* lastVertexToJson (Transaction*, + CollectionNameResolver*) const; + + }; + + + + } // traverser + } // arango +} // triagens + +#endif