1#pragma once
2
3#include <Common/LRUCache.h>
4#include <Common/SipHash.h>
5#include <Common/UInt128.h>
6#include <Common/ProfileEvents.h>
7#include <IO/BufferWithOwnMemory.h>
8
9
10namespace ProfileEvents
11{
12 extern const Event UncompressedCacheHits;
13 extern const Event UncompressedCacheMisses;
14 extern const Event UncompressedCacheWeightLost;
15}
16
17namespace DB
18{
19
20
21struct UncompressedCacheCell
22{
23 Memory<> data;
24 size_t compressed_size;
25 UInt32 additional_bytes;
26};
27
28struct UncompressedSizeWeightFunction
29{
30 size_t operator()(const UncompressedCacheCell & x) const
31 {
32 return x.data.size();
33 }
34};
35
36
37/** Cache of decompressed blocks for implementation of CachedCompressedReadBuffer. thread-safe.
38 */
39class UncompressedCache : public LRUCache<UInt128, UncompressedCacheCell, UInt128TrivialHash, UncompressedSizeWeightFunction>
40{
41private:
42 using Base = LRUCache<UInt128, UncompressedCacheCell, UInt128TrivialHash, UncompressedSizeWeightFunction>;
43
44public:
45 UncompressedCache(size_t max_size_in_bytes)
46 : Base(max_size_in_bytes) {}
47
48 /// Calculate key from path to file and offset.
49 static UInt128 hash(const String & path_to_file, size_t offset)
50 {
51 UInt128 key;
52
53 SipHash hash;
54 hash.update(path_to_file.data(), path_to_file.size() + 1);
55 hash.update(offset);
56 hash.get128(key.low, key.high);
57
58 return key;
59 }
60
61 MappedPtr get(const Key & key)
62 {
63 MappedPtr res = Base::get(key);
64
65 if (res)
66 ProfileEvents::increment(ProfileEvents::UncompressedCacheHits);
67 else
68 ProfileEvents::increment(ProfileEvents::UncompressedCacheMisses);
69
70 return res;
71 }
72
73private:
74 void onRemoveOverflowWeightLoss(size_t weight_loss) override
75 {
76 ProfileEvents::increment(ProfileEvents::UncompressedCacheWeightLost, weight_loss);
77 }
78};
79
80using UncompressedCachePtr = std::shared_ptr<UncompressedCache>;
81
82}
83