//////////////////////////////////////////////////////////////////////////////// /// 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 Jan Steemann //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_WAL_SLOTS_H #define ARANGOD_WAL_SLOTS_H 1 #include "Basics/Common.h" #include "Basics/ConditionVariable.h" #include "Basics/Mutex.h" #include "Wal/Logfile.h" #include "Wal/Slot.h" #include "Wal/SyncRegion.h" namespace arangodb { namespace wal { class LogfileManager; struct SlotInfoCopy { explicit SlotInfoCopy(Slot const* slot) : mem(slot->mem()), size(slot->size()), logfileId(slot->logfileId()), tick(slot->tick()), errorCode(TRI_ERROR_NO_ERROR) {} explicit SlotInfoCopy(int errorCode) : mem(nullptr), size(0), logfileId(0), tick(0), errorCode(errorCode) {} void const* mem; uint32_t const size; Logfile::IdType const logfileId; Slot::TickType const tick; int const errorCode; }; struct SlotInfo { explicit SlotInfo(int errorCode) : slot(nullptr), mem(nullptr), size(0), errorCode(errorCode) {} explicit SlotInfo(Slot* slot) : slot(slot), mem(slot->mem()), size(slot->size()), errorCode(TRI_ERROR_NO_ERROR) {} SlotInfo() : SlotInfo(TRI_ERROR_NO_ERROR) {} Slot* slot; void const* mem; uint32_t size; int errorCode; }; class Slots { private: Slots(Slots const&) = delete; Slots& operator=(Slots const&) = delete; public: ////////////////////////////////////////////////////////////////////////////// /// @brief create the slots ////////////////////////////////////////////////////////////////////////////// Slots(LogfileManager*, size_t, Slot::TickType); ////////////////////////////////////////////////////////////////////////////// /// @brief destroy the slots ////////////////////////////////////////////////////////////////////////////// ~Slots(); public: ////////////////////////////////////////////////////////////////////////////// /// @brief get the statistics of the slots ////////////////////////////////////////////////////////////////////////////// void statistics(Slot::TickType&, Slot::TickType&, Slot::TickType&, uint64_t&); ////////////////////////////////////////////////////////////////////////////// /// @brief execute a flush operation ////////////////////////////////////////////////////////////////////////////// int flush(bool); ////////////////////////////////////////////////////////////////////////////// /// @brief return the last committed tick ////////////////////////////////////////////////////////////////////////////// Slot::TickType lastCommittedTick(); ////////////////////////////////////////////////////////////////////////////// /// @brief return the next unused slot ////////////////////////////////////////////////////////////////////////////// SlotInfo nextUnused(uint32_t); SlotInfo nextUnused(TRI_voc_tick_t, TRI_voc_cid_t, uint32_t); ////////////////////////////////////////////////////////////////////////////// /// @brief return a used slot, allowing its synchronization ////////////////////////////////////////////////////////////////////////////// void returnUsed(SlotInfo&, bool); ////////////////////////////////////////////////////////////////////////////// /// @brief get the next synchronizable region ////////////////////////////////////////////////////////////////////////////// SyncRegion getSyncRegion(); ////////////////////////////////////////////////////////////////////////////// /// @brief return a region to the freelist ////////////////////////////////////////////////////////////////////////////// void returnSyncRegion(SyncRegion const&); ////////////////////////////////////////////////////////////////////////////// /// @brief get the current open region of a logfile /// this uses the slots lock ////////////////////////////////////////////////////////////////////////////// void getActiveLogfileRegion(Logfile*, char const*&, char const*&); ////////////////////////////////////////////////////////////////////////////// /// @brief get the current tick range of a logfile /// this uses the slots lock ////////////////////////////////////////////////////////////////////////////// void getActiveTickRange(Logfile*, TRI_voc_tick_t&, TRI_voc_tick_t&); ////////////////////////////////////////////////////////////////////////////// /// @brief close a logfile ////////////////////////////////////////////////////////////////////////////// int closeLogfile(Slot::TickType&, bool&); ////////////////////////////////////////////////////////////////////////////// /// @brief write a header marker ////////////////////////////////////////////////////////////////////////////// int writeHeader(Slot*); ////////////////////////////////////////////////////////////////////////////// /// @brief writes a prologue for a document/remove marker ////////////////////////////////////////////////////////////////////////////// int writePrologue(Slot*, void*, TRI_voc_tick_t, TRI_voc_cid_t); ////////////////////////////////////////////////////////////////////////////// /// @brief write a footer marker ////////////////////////////////////////////////////////////////////////////// int writeFooter(Slot*); ////////////////////////////////////////////////////////////////////////////// /// @brief handout a region and advance the handout index ////////////////////////////////////////////////////////////////////////////// Slot::TickType handout(); ////////////////////////////////////////////////////////////////////////////// /// @brief wait until all data has been synced up to a certain marker ////////////////////////////////////////////////////////////////////////////// bool waitForTick(Slot::TickType); ////////////////////////////////////////////////////////////////////////////// /// @brief request a new logfile which can satisfy a marker of the /// specified size ////////////////////////////////////////////////////////////////////////////// int newLogfile(uint32_t, Logfile::StatusType& status); private: ////////////////////////////////////////////////////////////////////////////// /// @brief the logfile manager ////////////////////////////////////////////////////////////////////////////// LogfileManager* _logfileManager; ////////////////////////////////////////////////////////////////////////////// /// @brief condition variable for slots ////////////////////////////////////////////////////////////////////////////// basics::ConditionVariable _condition; ////////////////////////////////////////////////////////////////////////////// /// @brief mutex protecting the slots interface ////////////////////////////////////////////////////////////////////////////// Mutex _lock; ////////////////////////////////////////////////////////////////////////////// /// @brief all slots ////////////////////////////////////////////////////////////////////////////// Slot* _slots; ////////////////////////////////////////////////////////////////////////////// /// @brief the total number of slots ////////////////////////////////////////////////////////////////////////////// size_t const _numberOfSlots; ////////////////////////////////////////////////////////////////////////////// /// @brief the number of currently free slots ////////////////////////////////////////////////////////////////////////////// size_t _freeSlots; ////////////////////////////////////////////////////////////////////////////// /// @brief whether or not someone is waiting for a slot ////////////////////////////////////////////////////////////////////////////// uint32_t _waiting; ////////////////////////////////////////////////////////////////////////////// /// @brief the index of the slot to hand out next ////////////////////////////////////////////////////////////////////////////// size_t _handoutIndex; ////////////////////////////////////////////////////////////////////////////// /// @brief the index of the slot to recycle ////////////////////////////////////////////////////////////////////////////// size_t _recycleIndex; ////////////////////////////////////////////////////////////////////////////// /// @brief the current logfile to write into ////////////////////////////////////////////////////////////////////////////// Logfile* _logfile; ////////////////////////////////////////////////////////////////////////////// /// @brief last assigned tick value ////////////////////////////////////////////////////////////////////////////// Slot::TickType _lastAssignedTick; ////////////////////////////////////////////////////////////////////////////// /// @brief last committed tick value ////////////////////////////////////////////////////////////////////////////// Slot::TickType _lastCommittedTick; ////////////////////////////////////////////////////////////////////////////// /// @brief last committed data tick value ////////////////////////////////////////////////////////////////////////////// Slot::TickType _lastCommittedDataTick; ////////////////////////////////////////////////////////////////////////////// /// @brief number of log events handled ////////////////////////////////////////////////////////////////////////////// uint64_t _numEvents; ////////////////////////////////////////////////////////////////////////////// /// @brief last written database id (in prologue marker) ////////////////////////////////////////////////////////////////////////////// TRI_voc_tick_t _lastDatabaseId; ////////////////////////////////////////////////////////////////////////////// /// @brief last written collection id (in prologue marker) ////////////////////////////////////////////////////////////////////////////// TRI_voc_cid_t _lastCollectionId; }; } } #endif