1
0
Fork 0
arangodb/arangod/Cache/Metadata.h

203 lines
8.8 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// 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 <atomic>
#include <cstdint>
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(uint64_t limit);
//////////////////////////////////////////////////////////////////////////////
/// @brief Initializes record from an existing record.
//////////////////////////////////////////////////////////////////////////////
Metadata(Metadata const& other);
//////////////////////////////////////////////////////////////////////////////
/// @brief Links the metadata object to an actual cache.
//////////////////////////////////////////////////////////////////////////////
void link(std::shared_ptr<Cache> cache);
//////////////////////////////////////////////////////////////////////////////
/// @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> 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> _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