//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2017 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 Simon Grätzer //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_STORAGE_ENGINE_WAL_ACCESS_H #define ARANGOD_STORAGE_ENGINE_WAL_ACCESS_H 1 #include #include "Basics/Result.h" #include "Utils/CollectionGuard.h" #include "Utils/DatabaseGuard.h" #include "VocBase/voc-types.h" #include namespace arangodb { struct WalAccessResult { WalAccessResult() : WalAccessResult(TRI_ERROR_NO_ERROR, false, 0, 0, 0) {} WalAccessResult(int code, bool ft, TRI_voc_tick_t included, TRI_voc_tick_t lastScannedTick, TRI_voc_tick_t latest) : _result(code), _fromTickIncluded(ft), _lastIncludedTick(included), _lastScannedTick(lastScannedTick), _latestTick(latest) {} /* WalAccessResult(WalAccessResult const& other) = default; WalAccessResult& operator=(WalAccessResult const& other) = default; */ bool fromTickIncluded() const { return _fromTickIncluded; } TRI_voc_tick_t lastIncludedTick() const { return _lastIncludedTick; } TRI_voc_tick_t lastScannedTick() const { return _lastScannedTick; } void lastScannedTick(TRI_voc_tick_t tick) { _lastScannedTick = tick; } TRI_voc_tick_t latestTick() const { return _latestTick; } WalAccessResult& reset(int errorNumber, bool ft, TRI_voc_tick_t included, TRI_voc_tick_t lastScannedTick, TRI_voc_tick_t latest) { _result.reset(errorNumber); _fromTickIncluded = ft; _lastIncludedTick = included; _lastScannedTick = lastScannedTick; _latestTick = latest; return *this; } // forwarded methods bool ok() const { return _result.ok(); } bool fail() const { return _result.fail(); } int errorNumber() const { return _result.errorNumber(); } std::string errorMessage() const { return _result.errorMessage(); } void reset(Result const& other) { _result.reset(); } // access methods Result const& result() const& { return _result; } Result result() && { return std::move(_result); } private: Result _result; bool _fromTickIncluded; TRI_voc_tick_t _lastIncludedTick; TRI_voc_tick_t _lastScannedTick; TRI_voc_tick_t _latestTick; }; /// @brief StorageEngine agnostic wal access interface. /// TODO: add methods for _admin/wal/ and get rid of engine specific handlers class WalAccess { WalAccess(WalAccess const&) = delete; WalAccess& operator=(WalAccess const&) = delete; protected: WalAccess() {} virtual ~WalAccess() {} public: struct Filter { Filter() {} /// tick last scanned by the last iteration /// is used to find batches in rocksdb uint64_t tickLastScanned = 0; /// first tick to use uint64_t tickStart = 0; /// last tick to include uint64_t tickEnd = UINT64_MAX; /// In case collection is == 0, bool includeSystem = false; /// export _queues and _jobs collection bool includeFoxxQueues = false; /// only output markers from this database TRI_voc_tick_t vocbase = 0; /// Only output data from this collection /// FIXME: make a set of collections TRI_voc_cid_t collection = 0; /// only include these transactions, up to /// (not including) firstRegularTick std::unordered_set transactionIds; /// @brief starting from this tick ignore transactionIds TRI_voc_tick_t firstRegularTick = 0; }; typedef std::function MarkerCallback; typedef std::function TransactionCallback; /// {"tickMin":"123", "tickMax":"456", /// "server":{"version":"3.2", "serverId":"abc"}} virtual Result tickRange(std::pair& minMax) const = 0; /// {"lastTick":"123", /// "server":{"version":"3.2", /// "serverId":"abc"}, /// "clients": { /// "serverId": "ass", "lastTick":"123", ... /// }} /// virtual TRI_voc_tick_t lastTick() const = 0; /// should return the list of transactions started, but not committed in that /// range (range can be adjusted) virtual WalAccessResult openTransactions(Filter const& filter, TransactionCallback const&) const = 0; virtual WalAccessResult tail(Filter const& filter, size_t chunkSize, TRI_voc_tid_t barrierId, MarkerCallback const&) const = 0; }; /// @brief helper class used to resolve vocbases /// and collections from wal markers in an efficient way struct WalAccessContext { WalAccessContext(WalAccess::Filter const& filter, WalAccess::MarkerCallback const& c) : _filter(filter), _callback(c), _responseSize(0) {} ~WalAccessContext() {} /// @brief check if db should be handled, might already be deleted bool shouldHandleDB(TRI_voc_tick_t dbid) const; /// @brief check if view should be handled, might already be deleted bool shouldHandleView(TRI_voc_tick_t dbid, TRI_voc_cid_t vid) const; /// @brief Check if collection is in filter, will load collection /// and prevent deletion bool shouldHandleCollection(TRI_voc_tick_t dbid, TRI_voc_cid_t cid); /// @brief try to get collection, may return null TRI_vocbase_t* loadVocbase(TRI_voc_tick_t dbid); LogicalCollection* loadCollection(TRI_voc_tick_t dbid, TRI_voc_cid_t cid); /// @brief get global unique id /*std::string const& cidToUUID(TRI_voc_tick_t dbid, TRI_voc_cid_t cid); /// @brief cid to collection name std::string cidToName(TRI_voc_tick_t dbid, TRI_voc_cid_t cid);*/ public: /// @brief arbitrary collection filter (inclusive) const WalAccess::Filter _filter; /// @brief callback for marker output WalAccess::MarkerCallback _callback; /// @brief current response size size_t _responseSize; /// @brief result builder velocypack::Builder _builder; /// @brief cache the vocbases std::map _vocbases; // @brief collection replication UUID cache std::map _collectionCache; }; } // namespace arangodb #endif