Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoupling local cache function and cache algorithm #38048

Merged
Next Next commit
Decoupling cache functions and algorithms
  • Loading branch information
KinderRiven committed Aug 10, 2022
commit 7f54fa726b8d6f2207bad8bdde4effed980e8eaa
2 changes: 1 addition & 1 deletion src/Common/FileSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ using FileSegments = std::list<FileSegmentPtr>;
class FileSegment : boost::noncopyable
{

friend class LRUFileCache;
friend class FileCache;
friend struct FileSegmentsHolder;
friend class FileSegmentRangeWriter;

Expand Down
92 changes: 92 additions & 0 deletions src/Common/IFileCachePriority.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#include <list>
#include <memory>
#include <mutex>

namespace DB
{

class IFileCachePriority;
using FileCachePriorityPtr = std::shared_ptr<IFileCachePriority>;

/// IFileCachePriority is used to maintain the priority of cached data.
class IFileCachePriority
{
public:
using Key = UInt128;

class IIterator;
friend class IIterator;
using Iterator = std::shared_ptr<IIterator>;

struct FileCacheRecord
{
Key key;
size_t offset;
size_t size;
size_t hits = 0;

FileCacheRecord(const Key & key_, size_t offset_, size_t size_) : key(key_), offset(offset_), size(size_) { }
};

/// It provides an iterator to traverse the cache priority. Under normal circumstances,
/// the iterator can only return the records that have been directly swapped out.
/// For example, in the LRU algorithm, it can traverse all records, but in the LRU-K, it
/// can only traverse the records in the low priority queue.
class IIterator
{
public:
virtual ~IIterator() = default;

virtual void next() = 0;

virtual bool vaild() const = 0;

/// Mark a cache record as recently used, it will update the priority
/// of the cache record according to different cache algorithms.
virtual void use(std::lock_guard<std::mutex> & cache_lock) = 0;

/// Deletes an existing cached record.
virtual void remove(std::lock_guard<std::mutex> & cache_lock) = 0;

virtual Key & key() const = 0;

virtual size_t offset() const = 0;

virtual size_t size() const = 0;

virtual size_t hits() const = 0;

virtual Iterator getSnapshot() = 0;

virtual void incrementSize(size_t size_increment, std::lock_guard<std::mutex> & cache_lock) = 0;
};

public:
virtual ~IFileCachePriority() = default;

/// Add a cache record that did not exist before, and throw a
/// logical exception if the cache block already exists.
virtual Iterator add(const Key & key, size_t offset, size_t size, std::lock_guard<std::mutex> & cache_lock) = 0;

/// Query whether a cache record exists. If it exists, return true. If not, return false.
virtual bool contains(const Key & key, size_t offset, std::lock_guard<std::mutex> & cache_lock) = 0;

virtual void removeAll(std::lock_guard<std::mutex> & cache_lock) = 0;

/// Returns an iterator pointing to the lowest priority cached record.
/// We can traverse all cached records through the iterator's next().
virtual Iterator getNewIterator(std::lock_guard<std::mutex> & cache_lock) = 0;

virtual size_t getElementsNum(std::lock_guard<std::mutex> & cache_lock) const = 0;

size_t getCacheSize(std::lock_guard<std::mutex> &) const { return cache_size; }

virtual std::string toString(std::lock_guard<std::mutex> & cache_lock) const = 0;

protected:
size_t max_cache_size = 0;
size_t cache_size = 0;
};
};
Loading