blob: 89f8696181141396516d51bd76640a848f10c6eb (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#pragma once
#include <list>
#include <Interpreters/Cache/IFileCachePriority.h>
#include <Interpreters/Cache/FileCacheKey.h>
#include <Common/logger_useful.h>
#include "Interpreters/Cache/Guards.h"
namespace CurrentMetrics
{
extern const Metric FilesystemCacheSizeLimit;
}
namespace DB
{
/// Based on the LRU algorithm implementation, the record with the lowest priority is stored at
/// the head of the queue, and the record with the highest priority is stored at the tail.
class LRUFileCachePriority : public IFileCachePriority
{
private:
class LRUFileCacheIterator;
using LRUQueue = std::list<Entry>;
using LRUQueueIterator = typename LRUQueue::iterator;
public:
LRUFileCachePriority(size_t max_size_, size_t max_elements_) : IFileCachePriority(max_size_, max_elements_)
{
CurrentMetrics::set(CurrentMetrics::FilesystemCacheSizeLimit, max_size_);
}
size_t getSize(const CacheGuard::Lock &) const override { return current_size; }
size_t getElementsCount(const CacheGuard::Lock &) const override { return current_elements_num; }
Iterator add(KeyMetadataPtr key_metadata, size_t offset, size_t size, const CacheGuard::Lock &) override;
void pop(const CacheGuard::Lock &) override;
void removeAll(const CacheGuard::Lock &) override;
void iterate(IterateFunc && func, const CacheGuard::Lock &) override;
void shuffle(const CacheGuard::Lock &) override;
private:
void updateElementsCount(int64_t num);
void updateSize(int64_t size);
LRUQueue queue;
Poco::Logger * log = &Poco::Logger::get("LRUFileCachePriority");
std::atomic<size_t> current_size = 0;
/// current_elements_num is not always equal to queue.size()
/// because of invalidated entries.
std::atomic<size_t> current_elements_num = 0;
LRUQueueIterator remove(LRUQueueIterator it);
};
class LRUFileCachePriority::LRUFileCacheIterator : public IFileCachePriority::IIterator
{
public:
LRUFileCacheIterator(
LRUFileCachePriority * cache_priority_,
LRUFileCachePriority::LRUQueueIterator queue_iter_);
const Entry & getEntry() const override { return *queue_iter; }
Entry & getEntry() override { return *queue_iter; }
size_t use(const CacheGuard::Lock &) override;
void remove(const CacheGuard::Lock &) override;
void invalidate() override;
void updateSize(int64_t size) override;
private:
void checkUsable() const;
LRUFileCachePriority * cache_priority;
mutable LRUFileCachePriority::LRUQueueIterator queue_iter;
};
}
|