//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2016 ArangoDB 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 Simon Grätzer //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGODB_PREGEL_GRAPH_STORE_H #define ARANGODB_PREGEL_GRAPH_STORE_H 1 #include #include #include #include #include "Basics/Mutex.h" #include "Cluster/ClusterInfo.h" #include "Pregel/Graph.h" #include "Pregel/GraphFormat.h" #include "Pregel/Iterators.h" #include "Pregel/TypedBuffer.h" #include "Utils/DatabaseGuard.h" struct TRI_vocbase_t; namespace arangodb { class LogicalCollection; namespace transaction { class Methods; } namespace pregel { template struct TypedBuffer; class WorkerConfig; template struct GraphFormat; //////////////////////////////////////////////////////////////////////////////// /// @brief carry graph data for a worker job. NOT THREAD SAFE ON DOCUMENT LOADS //////////////////////////////////////////////////////////////////////////////// template class GraphStore { public: GraphStore(TRI_vocbase_t* vocbase, GraphFormat* graphFormat); ~GraphStore(); uint64_t localVertexCount() const { return _localVerticeCount; } uint64_t localEdgeCount() const { return _localEdgeCount; } GraphFormat const* graphFormat() { return _graphFormat.get(); } // ====================== NOT THREAD SAFE =========================== void loadShards(WorkerConfig* state, std::function callback); void loadDocument(WorkerConfig* config, std::string const& documentID); void loadDocument(WorkerConfig* config, PregelShard sourceShard, PregelKey const& _key); // ====================================================================== // only thread safe if your threads coordinate access to memory locations RangeIterator vertexIterator(); RangeIterator vertexIterator(size_t start, size_t count); RangeIterator> edgeIterator(VertexEntry const* entry); /// get the pointer to the vertex V* mutableVertexData(VertexEntry const* entry); /// does nothing currently void replaceVertexData(VertexEntry const* entry, void* data, size_t size); /// Write results to database void storeResults(WorkerConfig* config, std::function callback); private: std::unordered_map _preallocateMemory(); void _loadVertices(size_t i, ShardID const& vertexShard, std::vector const& edgeShards, uint64_t vertexOffset); void _loadEdges(transaction::Methods* trx, ShardID const& shard, VertexEntry& vertexEntry, std::string const& documentID); void _storeVertices(std::vector const& globalShards, RangeIterator& it); std::unique_ptr _createTransaction(); private: DatabaseGuard _vocbaseGuard; const std::unique_ptr> _graphFormat; WorkerConfig* _config = nullptr; /// Holds vertex keys and pointers to vertex data and edges std::vector _index; /// Vertex data TypedBuffer* _vertexData = nullptr; /// Edges (and data) TypedBuffer>* _edges = nullptr; // cache the amount of vertices std::set _loadedShards; // hold the current position where the ith vertex shard can // start to write its data. At the end the offset should equal the // sum of the counts of all ith edge shards std::vector _edgeShardsOffset; // actual count of loaded vertices / edges std::atomic _localVerticeCount; std::atomic _localEdgeCount; std::atomic _runningThreads; bool _destroyed = false; }; } } #endif