From 9f1830b4c565bdf045a0c2d9c2ef69c6c050f7c6 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 Apr 2015 12:01:44 -0700 Subject: [PATCH] Started implementing the Expander function. Not et finished does not compile but i am moving over to a new machine --- arangod/Makefile.files | 1 + arangod/V8Server/V8Traverser.cpp | 300 +++++++++++++++++++++++++++++++ arangod/V8Server/V8Traverser.h | 30 ++++ arangod/V8Server/v8-vocbase.cpp | 3 +- lib/Basics/Traverser.cpp | 288 ++++++++--------------------- lib/Basics/Traverser.h | 53 ++++-- lib/CMakeLists.txt | 1 + 7 files changed, 443 insertions(+), 233 deletions(-) create mode 100644 arangod/V8Server/V8Traverser.cpp create mode 100644 arangod/V8Server/V8Traverser.h diff --git a/arangod/Makefile.files b/arangod/Makefile.files index 70c5f7254c..8a2605018f 100644 --- a/arangod/Makefile.files +++ b/arangod/Makefile.files @@ -106,6 +106,7 @@ arangod_libarangod_a_SOURCES = \ arangod/V8Server/V8PeriodicTask.cpp \ arangod/V8Server/V8QueueJob.cpp \ arangod/V8Server/V8TimerTask.cpp \ + arangod/V8Server/V8Traverser.cpp \ arangod/V8Server/v8-actions.cpp \ arangod/V8Server/v8-collection.cpp \ arangod/V8Server/v8-collection-util.cpp \ diff --git a/arangod/V8Server/V8Traverser.cpp b/arangod/V8Server/V8Traverser.cpp new file mode 100644 index 0000000000..fde287d3fc --- /dev/null +++ b/arangod/V8Server/V8Traverser.cpp @@ -0,0 +1,300 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief V8 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 "v8.h" +#include "V8/v8-conv.h" +#include "V8/v8-utils.h" +#include "V8Server/v8-vocbaseprivate.h" +#include "V8Server/v8-wrapshapedjson.h" +#include "V8Server/v8-vocindex.h" +#include "V8Server/v8-collection.h" +#include "Utils/transactions.h" +#include "Utils/V8ResolverGuard.h" +#include "Utils/CollectionNameResolver.h" +#include "Traverser.h" +#include "VocBase/key-generator.h" + +using namespace std; +using namespace triagens::basics; +using namespace triagens::arango; + +class SimpleEdgeExpander { + + private: + TRI_edge_direction_e forwardDirection; + TRI_edge_direction_e backwardDirection; + TRI_document_collection_t* edgeCollection; + CollectionNameResolver const* resolver; + + public: + void operator() ( Traverser::VertexId source, + Traverser::Direction dir, + vector& result + ) { + std::vector edges; + // Process Vertex Id! + size_t split; + char const* str = source.c_str(); + if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) { + // TODO Error Handling + return; + } + std::unique_ptr& key; + string& collectionName = string(str, split); + auto const length = str->length() - split - 1; + auto buffer = new char[length + 1]; + memcpy(buffer, *str + split + 1, length); + buffer[length] = '\0'; + key.reset(buffer); + + auto col = resolver->getCollectionStruct(collectionName); + if (col == nullptr) { + // collection not found + throw TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND; + } + auto collectionCId = col->_cid; + if (dir == Traverser::FORWARD) { + edges = TRI_LookupEdgesDocumentCollection(edgeCollection, forwardDirection, collectionCId, key.get()); + } else { + edges = TRI_LookupEdgesDocumentCollection(edgeCollection, backwardDirection, collectionCId, key.get()); + } + + // TODO Build result + } + SimpleEdgeExpander( + TRI_edge_direction_e edgeDirection, + TRI_document_collection_t* edgeCollection, + CollectionNameResolver const* resolver + ) : + edgeCollection(edgeCollection), + resolver(resolver) + { + if (edgeDirection == TRI_EDGE_OUT) { + forwardDirection = TRI_EDGE_OUT; + backwardDirection = TRI_EDGE_IN; + } else if (edgeDirection == TRI_EDGE_IN) { + forwardDirection = TRI_EDGE_IN; + backwardDirection = TRI_EDGE_OUT; + } else { + forwardDirection = TRI_EDGE_ANY; + backwardDirection = TRI_EDGE_ANY; + } + }; +} + + +struct LocalCollectionGuard { + LocalCollectionGuard (TRI_vocbase_col_t* collection) + : _collection(collection) { + } + + ~LocalCollectionGuard () { + if (_collection != nullptr && ! _collection->_isLocal) { + FreeCoordinatorCollection(_collection); + } + } + + TRI_vocbase_col_t* _collection; +}; + +void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo& args) { + v8::Isolate* isolate = args.GetIsolate(); + v8::HandleScope scope(isolate); + + if (args.Length() < 4 || args.Length() > 5) { + TRI_V8_THROW_EXCEPTION_USAGE("AQL_SHORTEST_PATH(, , , , )"); + } + + std::unique_ptr key; + TRI_vocbase_t* vocbase; + TRI_vocbase_col_t const* col = nullptr; + + vocbase = GetContextVocBase(isolate); + + vector readCollections; + vector writeCollections; + TRI_voc_cid_t vertexCollectionCId; + TRI_voc_cid_t edgeCollectionCId; + TRI_voc_rid_t rid; + + double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL); + bool embed = false; + bool waitForSync = false; + + // get the vertex collection + if (! args[0]->IsString()) { + TRI_V8_THROW_TYPE_ERROR("expecting string for "); + } + string vertexCollectionName = TRI_ObjectToString(args[0]); + + // get the edge collection + if (! args[1]->IsString()) { + TRI_V8_THROW_TYPE_ERROR("expecting string for "); + } + string const edgeCollectionName = TRI_ObjectToString(args[1]); + + vocbase = GetContextVocBase(isolate); + + if (vocbase == nullptr) { + TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND); + } + V8ResolverGuard resolver(vocbase); + + readCollections.push_back(vertexCollectionName); + readCollections.push_back(edgeCollectionName); + + if (! args[2]->IsString()) { + TRI_V8_THROW_TYPE_ERROR("expecting string for "); + } + + + std::string vertexColName; + + if (! ExtractDocumentHandle(isolate, args[2], vertexColName, key, rid)) { + TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD); + } + + if (key.get() == nullptr) { + TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD); + } + + TRI_ASSERT(key.get() != nullptr); + + // IHHF isCoordinator + + // Start Transaction to collect all parts of the path + ExplicitTransaction trx( + vocbase, + readCollections, + writeCollections, + lockTimeout, + waitForSync, + embed + ); + + int res = trx.begin(); + + if (res != TRI_ERROR_NO_ERROR) { + TRI_V8_THROW_EXCEPTION(res); + } + + col = resolver.getResolver()->getCollectionStruct(vertexCollectionName); + if (col == nullptr) { + // collection not found + TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + vertexCollectionCId = col->_cid; + if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) { + TRI_V8_THROW_EXCEPTION_MEMORY(); + } + + col = resolver.getResolver()->getCollectionStruct(edgeCollectionName); + if (col == nullptr) { + // collection not found + TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + edgeCollectionCId = col->_cid; + if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) { + TRI_V8_THROW_EXCEPTION_MEMORY(); + } + + v8::Handle result; + v8::Handle documents; + + // This is how to get the data out of the collections! + // Vertices + TRI_doc_mptr_copy_t document; + res = trx.readSingle(trx.trxCollection(vertexCollectionCId), &document, key.get()); + + // Edges TRI_EDGE_OUT is hardcoded + TRI_document_collection_t* ecol = trx.trxCollection(edgeCollectionCId)->_collection->_collection; + std::vector&& edges = TRI_LookupEdgesDocumentCollection(ecol, TRI_EDGE_OUT, vertexCollectionCId, key.get()); + + // Add Dijkstra here + + // Now build up the result use Subtransactions for each used collection + if (res == TRI_ERROR_NO_ERROR) { + { + // Collect all vertices + SingleCollectionReadOnlyTransaction subtrx(new V8TransactionContext(true), vocbase, vertexCollectionCId); + + res = subtrx.begin(); + + if (res != TRI_ERROR_NO_ERROR) { + TRI_V8_THROW_EXCEPTION(res); + } + + result = TRI_WrapShapedJson(isolate, subtrx, vertexCollectionCId, document.getDataPtr()); + + if (document.getDataPtr() == nullptr) { + res = TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND; + TRI_V8_THROW_EXCEPTION(res); + } + + res = subtrx.finish(res); + } + + { + // Collect all edges + SingleCollectionReadOnlyTransaction subtrx2(new V8TransactionContext(true), vocbase, edgeCollectionCId); + + res = subtrx2.begin(); + + if (res != TRI_ERROR_NO_ERROR) { + TRI_V8_THROW_EXCEPTION(res); + } + + bool error = false; + + uint32_t const n = static_cast(edges.size()); + documents = v8::Array::New(isolate, static_cast(n)); + for (size_t j = 0; j < n; ++j) { + v8::Handle doc = TRI_WrapShapedJson(isolate, subtrx2, edgeCollectionCId, edges[j].getDataPtr()); + + if (doc.IsEmpty()) { + error = true; + break; + } + else { + documents->Set(static_cast(j), doc); + } + } + if (error) { + TRI_V8_THROW_EXCEPTION_MEMORY(); + } + + res = subtrx2.finish(res); + } + } + res = trx.finish(res); + + // Not yet correct. Needs to build an object first. + // TRI_V8_RETURN(result); + TRI_V8_RETURN(documents); +} diff --git a/arangod/V8Server/V8Traverser.h b/arangod/V8Server/V8Traverser.h new file mode 100644 index 0000000000..fd0735086b --- /dev/null +++ b/arangod/V8Server/V8Traverser.h @@ -0,0 +1,30 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief V8 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 +//////////////////////////////////////////////////////////////////////////////// + + diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 3c55ba373f..bbe73e1733 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -52,7 +52,6 @@ #include "Wal/LogfileManager.h" #include "VocBase/auth.h" -#include "VocBase/traversal.h" #include "v8.h" #include "V8/JSLoader.h" @@ -1483,7 +1482,7 @@ static void JS_QueryIsKilledAql (const v8::FunctionCallbackInfo& args //////////////////////////////////////////////////////////////////////////////// static void JS_QueryShortestPath (const v8::FunctionCallbackInfo& args) { - TRI_RunDijkstraSearch(args); +// TRI_RunDijkstraSearch(args); } diff --git a/lib/Basics/Traverser.cpp b/lib/Basics/Traverser.cpp index 5826b46c5c..ebcb3afc17 100644 --- a/lib/Basics/Traverser.cpp +++ b/lib/Basics/Traverser.cpp @@ -28,20 +28,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "Traverser.h" - -/* -#include "v8.h" -#include "V8/v8-conv.h" -#include "V8/v8-utils.h" -#include "V8Server/v8-vocbaseprivate.h" -#include "V8Server/v8-wrapshapedjson.h" -#include "V8Server/v8-vocindex.h" -#include "V8Server/v8-collection.h" -#include "Utils/transactions.h" -#include "Utils/V8ResolverGuard.h" - -using namespace triagens::arango; -*/ +#include using namespace std; using namespace triagens::basics; @@ -100,21 +87,33 @@ void Traverser::lookupPeer (ThreadInfo& info, //////////////////////////////////////////////////////////////////////////////// void Traverser::searchFromVertex ( - ThreadInfo& myInfo, - ThreadInfo& peerInfo, + ThreadInfo myInfo, + ThreadInfo peerInfo, VertexId start, Direction dir ) { - insertNeighbor(myInfo, start, nullptr, nullptr, 0); + insertNeighbor(myInfo, start, "", "", 0); auto nextVertex = myInfo.queue.begin(); + std::vector neighbors; + // Iterate while no bingo found and // there still is a vertex on the stack. while (!bingo && nextVertex != myInfo.queue.end()) { myInfo.queue.erase(nextVertex); - + _neighborFunction(nextVertex->vertex, dir, neighbors); + for (auto neighbor : neighbors) { + insertNeighbor(myInfo, neighbor.neighbor, nextVertex->vertex, + neighbor.edge, nextVertex->weight + neighbor.weight); + } + lookupPeer(peerInfo, nextVertex->vertex, nextVertex->weight); + myInfo.mutex.lock(); + // Can move nextVertexLookup up? + auto nextVertexLookup = myInfo.lookup.find(nextVertex->vertex); + nextVertexLookup->second.done = true; + myInfo.mutex.unlock(); nextVertex = myInfo.queue.begin(); } - + // No possible path, can possibly terminate other thread }; //////////////////////////////////////////////////////////////////////////////// @@ -122,204 +121,57 @@ void Traverser::searchFromVertex ( //////////////////////////////////////////////////////////////////////////////// Traverser::Path* Traverser::ShortestPath (VertexId const& start, - VertexId const& target, - Direction direction) { + VertexId const& target) { - return nullptr; + std::vector r_vertices; + std::vector r_edges; + highscore = 1e50; + + // Forward + _forwardLookup.clear(); + _forwardQueue.clear(); + ThreadInfo forwardInfo(_forwardLookup, _forwardQueue, _forwardMutex); + + _backwardLookup.clear(); + _backwardQueue.clear(); + ThreadInfo backwardInfo(_backwardLookup, _backwardQueue, _backwardMutex); + + std::thread forwardSearcher(&Traverser::searchFromVertex, + this, forwardInfo, backwardInfo, start, FORWARD); + std::thread backwardSearcher(&Traverser::searchFromVertex, + this, backwardInfo, forwardInfo, target, BACKWARD); + forwardSearcher.join(); + backwardSearcher.join(); + + // TODO Return result + if (!bingo) { + return nullptr; + } + + auto pathLookup = _forwardLookup.find(intermediate); + // FORWARD Go path back from intermediate -> start. + // Insert all vertices and edges at front of vector + // Do NOT! insert the intermediate vertex + do { + r_edges.insert(r_edges.begin(), pathLookup->second.edge); + r_vertices.insert(r_vertices.begin(), pathLookup->first); + pathLookup = _forwardLookup.find(pathLookup->second.predecessor); + } while (pathLookup->second.predecessor != ""); + r_vertices.insert(r_vertices.begin(), pathLookup->first); + + // BACKWARD Go path back from intermediate -> target. + // Insert all vertices and edges at back of vector + // Also insert the intermediate vertex + pathLookup = _backwardLookup.find(intermediate); + r_vertices.push_back(intermediate); + r_edges.push_back(pathLookup->second.edge); + pathLookup = _backwardLookup.find(pathLookup->second.predecessor); + while (pathLookup->second.predecessor != "") { + r_vertices.push_back(pathLookup->first); + r_edges.push_back(pathLookup->second.edge); + pathLookup = _backwardLookup.find(pathLookup->second.predecessor); + } + r_vertices.push_back(pathLookup->first); + Path* res = new Path(r_vertices, r_edges, highscore); + return res; }; - -/* - - - -struct LocalCollectionGuard { - LocalCollectionGuard (TRI_vocbase_col_t* collection) - : _collection(collection) { - } - - ~LocalCollectionGuard () { - if (_collection != nullptr && ! _collection->_isLocal) { - FreeCoordinatorCollection(_collection); - } - } - - TRI_vocbase_col_t* _collection; -}; - -void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo& args) { - v8::Isolate* isolate = args.GetIsolate(); - v8::HandleScope scope(isolate); - - if (args.Length() < 4 || args.Length() > 5) { - TRI_V8_THROW_EXCEPTION_USAGE("AQL_SHORTEST_PATH(, , , , )"); - } - - std::unique_ptr key; - TRI_vocbase_t* vocbase; - TRI_vocbase_col_t const* col = nullptr; - - vocbase = GetContextVocBase(isolate); - - vector readCollections; - vector writeCollections; - TRI_voc_cid_t vertexCollectionCId; - TRI_voc_cid_t edgeCollectionCId; - TRI_voc_rid_t rid; - - double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL); - bool embed = false; - bool waitForSync = false; - - // get the vertex collection - if (! args[0]->IsString()) { - TRI_V8_THROW_TYPE_ERROR("expecting string for "); - } - string vertexCollectionName = TRI_ObjectToString(args[0]); - - // get the edge collection - if (! args[1]->IsString()) { - TRI_V8_THROW_TYPE_ERROR("expecting string for "); - } - string const edgeCollectionName = TRI_ObjectToString(args[1]); - - vocbase = GetContextVocBase(isolate); - - if (vocbase == nullptr) { - TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND); - } - V8ResolverGuard resolver(vocbase); - - readCollections.push_back(vertexCollectionName); - readCollections.push_back(edgeCollectionName); - - if (! args[2]->IsString()) { - TRI_V8_THROW_TYPE_ERROR("expecting string for "); - } - - - std::string vertexColName; - - if (! ExtractDocumentHandle(isolate, args[2], vertexColName, key, rid)) { - TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD); - } - - if (key.get() == nullptr) { - TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD); - } - - TRI_ASSERT(key.get() != nullptr); - - // IHHF isCoordinator - - // Start Transaction to collect all parts of the path - ExplicitTransaction trx( - vocbase, - readCollections, - writeCollections, - lockTimeout, - waitForSync, - embed - ); - - int res = trx.begin(); - - if (res != TRI_ERROR_NO_ERROR) { - TRI_V8_THROW_EXCEPTION(res); - } - - col = resolver.getResolver()->getCollectionStruct(vertexCollectionName); - if (col == nullptr) { - // collection not found - TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); - } - vertexCollectionCId = col->_cid; - if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) { - TRI_V8_THROW_EXCEPTION_MEMORY(); - } - - col = resolver.getResolver()->getCollectionStruct(edgeCollectionName); - if (col == nullptr) { - // collection not found - TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); - } - edgeCollectionCId = col->_cid; - if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) { - TRI_V8_THROW_EXCEPTION_MEMORY(); - } - - v8::Handle result; - v8::Handle documents; - - // This is how to get the data out of the collections! - // Vertices - TRI_doc_mptr_copy_t document; - res = trx.readSingle(trx.trxCollection(vertexCollectionCId), &document, key.get()); - - // Edges TRI_EDGE_OUT is hardcoded - TRI_document_collection_t * ecol = trx.trxCollection(edgeCollectionCId)->_collection->_collection; - std::cout << key.get() << "\n"; - std::vector&& edges = TRI_LookupEdgesDocumentCollection(ecol, TRI_EDGE_OUT, vertexCollectionCId, key.get()); - - // Add Dijkstra here - - // Now build up the result use Subtransactions for each used collection - if (res == TRI_ERROR_NO_ERROR) { - { - // Collect all vertices - SingleCollectionReadOnlyTransaction subtrx(new V8TransactionContext(true), vocbase, vertexCollectionCId); - - res = subtrx.begin(); - - if (res != TRI_ERROR_NO_ERROR) { - TRI_V8_THROW_EXCEPTION(res); - } - - result = TRI_WrapShapedJson(isolate, subtrx, vertexCollectionCId, document.getDataPtr()); - - if (document.getDataPtr() == nullptr) { - res = TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND; - TRI_V8_THROW_EXCEPTION(res); - } - - res = subtrx.finish(res); - } - - { - // Collect all edges - SingleCollectionReadOnlyTransaction subtrx2(new V8TransactionContext(true), vocbase, edgeCollectionCId); - - res = subtrx2.begin(); - - if (res != TRI_ERROR_NO_ERROR) { - TRI_V8_THROW_EXCEPTION(res); - } - - bool error = false; - - uint32_t const n = static_cast(edges.size()); - documents = v8::Array::New(isolate, static_cast(n)); - for (size_t j = 0; j < n; ++j) { - v8::Handle doc = TRI_WrapShapedJson(isolate, subtrx2, edgeCollectionCId, edges[j].getDataPtr()); - - if (doc.IsEmpty()) { - error = true; - break; - } - else { - documents->Set(static_cast(j), doc); - } - } - if (error) { - TRI_V8_THROW_EXCEPTION_MEMORY(); - } - - res = subtrx2.finish(res); - } - } - res = trx.finish(res); - - // Not yet correct. Needs to build an object first. - // TRI_V8_RETURN(result); - TRI_V8_RETURN(documents); -} -*/ diff --git a/lib/Basics/Traverser.h b/lib/Basics/Traverser.h index 64a6823e5e..040b1f0199 100644 --- a/lib/Basics/Traverser.h +++ b/lib/Basics/Traverser.h @@ -27,8 +27,8 @@ /// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGODB_VOC_BASE_TRAVERSAL_H -#define ARANGODB_VOC_BASE_TRAVERSAL_H 1 +#ifndef ARANGODB_TRAVERSAL_H +#define ARANGODB_TRAVERSAL_H 1 #include "Basics/Common.h" @@ -61,12 +61,30 @@ namespace triagens { std::vector vertices; std::vector edges; EdgeWeight weight; + + Path ( + std::vector vertices, + std::vector edges, + EdgeWeight weight + ) : vertices(vertices), + edges(edges), + weight(weight) { + }; }; struct Neighbor { VertexId neighbor; EdgeId edge; EdgeWeight weight; + + Neighbor ( + VertexId neighbor, + EdgeId edge, + EdgeWeight weight + ) : neighbor(neighbor), + edge(edge), + weight(weight) { + }; }; //////////////////////////////////////////////////////////////////////////////// @@ -75,7 +93,7 @@ namespace triagens { typedef enum {FORWARD, BACKWARD} Direction; typedef std::function& result)> - NeighborFunction; + ExpanderFunction; // ----------------------------------------------------------------------------- // --SECTION-- constructors and destructors @@ -85,7 +103,7 @@ namespace triagens { /// @brief create the Traverser //////////////////////////////////////////////////////////////////////////////// - Traverser (NeighborFunction const& n) : _neighborFunction(n) { + Traverser (ExpanderFunction const& n) : _neighborFunction(n) { }; //////////////////////////////////////////////////////////////////////////////// @@ -109,8 +127,7 @@ namespace triagens { // nullptr indicates there is no path Path* ShortestPath ( VertexId const& start, - VertexId const& target, - Direction direction + VertexId const& target ); // ----------------------------------------------------------------------------- @@ -155,11 +172,11 @@ namespace triagens { vertex(vertex) { }; - bool operator< (QueueInfo const& a) { - if (weight == a.weight) { - return vertex < a.vertex; + friend bool operator< (QueueInfo const& a, QueueInfo const& b) { + if (a.weight == b.weight) { + return a.vertex < b.vertex; } - return weight < a.weight; + return a.weight < b.weight; }; }; @@ -169,11 +186,21 @@ namespace triagens { std::unordered_map& lookup; std::set>& queue; std::mutex& mutex; + + ThreadInfo ( + std::unordered_map& lookup, + std::set>& queue, + std::mutex& mutex + ) : lookup(lookup), + queue(queue), + mutex(mutex) { + }; }; - NeighborFunction const& _neighborFunction; + ExpanderFunction const& _neighborFunction; + // Are they needed anyway?? // ShortestPath will create these variables std::unordered_map _forwardLookup; std::set> _forwardQueue; @@ -195,8 +222,8 @@ namespace triagens { VertexId neighbor, EdgeWeight weight ); - void searchFromVertex ( ThreadInfo& myInfo, - ThreadInfo& peerInfo, + void searchFromVertex ( ThreadInfo myInfo, + ThreadInfo peerInfo, VertexId start, Direction dir ); diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d25ea04adf..b8a4b3364a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -93,6 +93,7 @@ add_library( Basics/Thread.cpp Basics/ThreadPool.cpp Basics/Timing.cpp + Basics/Traversal.cpp Basics/tri-strings.cpp Basics/tri-zip.cpp Basics/Utf8Helper.cpp