//////////////////////////////////////////////////////////////////////////////// /// 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 Daniel H. Larkin //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGODB_CACHE_METADATA_H #define ARANGODB_CACHE_METADATA_H #include "Basics/Common.h" #include "Cache/State.h" #include #include namespace arangodb { namespace cache { class Cache; // forward declaration //////////////////////////////////////////////////////////////////////////////// /// @brief Metadata object to facilitate information sharing between individual /// Cache instances and Manager. //////////////////////////////////////////////////////////////////////////////// class Metadata { public: ////////////////////////////////////////////////////////////////////////////// /// @brief Initializes record with given information. ////////////////////////////////////////////////////////////////////////////// Metadata(std::shared_ptr cache, uint64_t limit, uint8_t* table = nullptr, uint32_t logSize = 0); ////////////////////////////////////////////////////////////////////////////// /// @brief Initializes record from an existing record. ////////////////////////////////////////////////////////////////////////////// Metadata(Metadata const& other); ////////////////////////////////////////////////////////////////////////////// /// @brief Locks the record. ////////////////////////////////////////////////////////////////////////////// void lock(); ////////////////////////////////////////////////////////////////////////////// /// @brief Unlocks the record. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// void unlock(); ////////////////////////////////////////////////////////////////////////////// /// @brief Returns true if the record is locked, false otherwise. ////////////////////////////////////////////////////////////////////////////// bool isLocked() const; ////////////////////////////////////////////////////////////////////////////// /// @brief Returns a shared pointer to the underlying cache. Requires record /// to be locked. ////////////////////////////////////////////////////////////////////////////// std::shared_ptr cache() const; ////////////////////////////////////////////////////////////////////////////// /// @brief Pointer to the table. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// uint8_t* table() const; ////////////////////////////////////////////////////////////////////////////// /// @brief The base-2 logarithm of the number of buckets in the table. /// Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// uint32_t logSize() const; ////////////////////////////////////////////////////////////////////////////// /// @brief Pointer to the auxiliary table. Requires record to be locked. /// /// Will typically be nullptr. This will be set to a non-null value prior to /// migration. During migration, both tables will temporarily be in use. Upon /// completion of migration, the tables are swapped and the old table is /// released to the manager. ////////////////////////////////////////////////////////////////////////////// uint8_t* auxiliaryTable() const; ////////////////////////////////////////////////////////////////////////////// /// @brief The base-2 logarithm of the number of buckets in the auxiliary /// table. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// uint32_t auxiliaryLogSize() const; ////////////////////////////////////////////////////////////////////////////// /// @brief The current memory usage of the cache in bytes. Requires record to /// be locked. ////////////////////////////////////////////////////////////////////////////// uint64_t usage() const; ////////////////////////////////////////////////////////////////////////////// /// @brief The soft usage limit for this cache. Requires record to be locked. /// /// Typically, this will be equal to the hard limit. It may be lower when the /// cache is resizing. If the current usage is below the soft limit, then new /// insertions are not allowed to exceed the soft limit. If the current usage /// is above the soft limit, then new insertions may occur as long as they do /// not exceed the hard limit; a background task will be working in parallel /// to remove older values to bring usage below the soft limit. ////////////////////////////////////////////////////////////////////////////// uint64_t softLimit() const; ////////////////////////////////////////////////////////////////////////////// /// @brief The hard usage limit for this cache. Requires record to be locked. /// /// Usage is guaranteed to remain under this value at all times. ////////////////////////////////////////////////////////////////////////////// uint64_t hardLimit() const; ////////////////////////////////////////////////////////////////////////////// /// @brief Adjusts usage by the specified amount if it will not violate /// limits. Requires record to be locked. /// /// Returns true if adjusted, false otherwise. Used by caches to check-and-set /// in a single operation to determine whether they can afford to store a new /// value. ////////////////////////////////////////////////////////////////////////////// bool adjustUsageIfAllowed(int64_t usageChange); ////////////////////////////////////////////////////////////////////////////// /// @brief Sets the soft and hard usage limits. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// bool adjustLimits(uint64_t softLimit, uint64_t hardLimit); ////////////////////////////////////////////////////////////////////////////// /// @brief Lets the manager grant a new table lease to the cache for /// migration. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// void grantAuxiliaryTable(uint8_t* table, uint32_t logSize); ////////////////////////////////////////////////////////////////////////////// /// @brief Swap the main and auxiliary tables (both pointers and sizes). /// Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// void swapTables(); ////////////////////////////////////////////////////////////////////////////// /// @brief Release the main table back to the manager. Requires record to be /// locked. ////////////////////////////////////////////////////////////////////////////// uint8_t* releaseTable(); ////////////////////////////////////////////////////////////////////////////// /// @brief Release the auxiliary table back to the manager. Requires record to /// be locked. ////////////////////////////////////////////////////////////////////////////// uint8_t* releaseAuxiliaryTable(); ////////////////////////////////////////////////////////////////////////////// /// @brief Checks if flag is set in state. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// bool isSet(State::Flag flag) const; ////////////////////////////////////////////////////////////////////////////// /// @brief Toggles flag in state. Requires record to be locked. ////////////////////////////////////////////////////////////////////////////// void toggleFlag(State::Flag flag); private: State _state; // pointer to underlying cache std::shared_ptr _cache; // vital information about memory usage uint64_t _usage; uint64_t _softLimit; uint64_t _hardLimit; // information about table leases uint8_t* _table; uint8_t* _auxiliaryTable; uint32_t _logSize; uint32_t _auxiliaryLogSize; }; }; // end namespace cache }; // end namespace arangodb #endif