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 | |
10 | namespace ProfileEvents |
11 | { |
12 | extern const Event UncompressedCacheHits; |
13 | extern const Event UncompressedCacheMisses; |
14 | extern const Event UncompressedCacheWeightLost; |
15 | } |
16 | |
17 | namespace DB |
18 | { |
19 | |
20 | |
21 | struct UncompressedCacheCell |
22 | { |
23 | Memory<> data; |
24 | size_t compressed_size; |
25 | UInt32 additional_bytes; |
26 | }; |
27 | |
28 | struct 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 | */ |
39 | class UncompressedCache : public LRUCache<UInt128, UncompressedCacheCell, UInt128TrivialHash, UncompressedSizeWeightFunction> |
40 | { |
41 | private: |
42 | using Base = LRUCache<UInt128, UncompressedCacheCell, UInt128TrivialHash, UncompressedSizeWeightFunction>; |
43 | |
44 | public: |
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 | |
73 | private: |
74 | void onRemoveOverflowWeightLoss(size_t weight_loss) override |
75 | { |
76 | ProfileEvents::increment(ProfileEvents::UncompressedCacheWeightLost, weight_loss); |
77 | } |
78 | }; |
79 | |
80 | using UncompressedCachePtr = std::shared_ptr<UncompressedCache>; |
81 | |
82 | } |
83 | |