src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
44 / 47
93.6%
Branches:
32 / 50
64.0%
Functions:
8 / 8
100.0%

storage/cache/lru/lru_cache.h
Line Branch Exec Source
1 #pragma once
2
3 #include <cstddef>
4 #include <list>
5 #include <mutex>
6 #include <unordered_map>
7 #include <vector>
8
9 #include "storage/cache/cache.h"
10
11 template <typename Key>
12 class LRUCachePolicy final : public CachePolicy<Key> {
13 public:
14 10 explicit LRUCachePolicy(size_t capacity) : capacity_(capacity) {}
15
16 64022 void OnInsert(const Key& key) override {
17
1/2
✓ Branch 1 taken 64022 times.
✗ Branch 2 not taken.
64022 std::lock_guard<std::mutex> lock(mutex_);
18
1/2
✓ Branch 1 taken 64022 times.
✗ Branch 2 not taken.
64022 TouchLocked(key);
19
1/2
✓ Branch 1 taken 64022 times.
✗ Branch 2 not taken.
64022 TrimToCapacityLocked();
20 64022 }
21
22 64006 void OnAccess(const Key& key) override {
23
1/2
✓ Branch 1 taken 64006 times.
✗ Branch 2 not taken.
64006 std::lock_guard<std::mutex> lock(mutex_);
24
1/2
✓ Branch 1 taken 64006 times.
✗ Branch 2 not taken.
64006 TouchLocked(key);
25 64006 }
26
27 678 std::vector<Key> Evict(size_t count) override {
28
1/2
✓ Branch 1 taken 678 times.
✗ Branch 2 not taken.
678 std::lock_guard<std::mutex> lock(mutex_);
29 678 std::vector<Key> evicted;
30
5/6
✓ Branch 0 taken 676 times.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 676 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 676 times.
678 if (count == 0 || order_.empty()) {
31 2 return evicted;
32 }
33
1/2
✓ Branch 1 taken 676 times.
✗ Branch 2 not taken.
676 evicted.reserve(count);
34
6/6
✓ Branch 0 taken 5358 times.
✓ Branch 1 taken 668 times.
✓ Branch 3 taken 5350 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 5350 times.
✓ Branch 6 taken 676 times.
6026 for (size_t i = 0; i < count && !order_.empty(); ++i) {
35 5350 const Key key = order_.back();
36 5350 order_.pop_back();
37
1/2
✓ Branch 1 taken 5350 times.
✗ Branch 2 not taken.
5350 map_.erase(key);
38
1/2
✓ Branch 1 taken 5350 times.
✗ Branch 2 not taken.
5350 evicted.push_back(key);
39 }
40 676 return evicted;
41 678 }
42
43 10 size_t Size() const override {
44
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 std::lock_guard<std::mutex> lock(mutex_);
45 20 return order_.size();
46 10 }
47
48 6 bool Contains(const Key& key) const {
49
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::lock_guard<std::mutex> lock(mutex_);
50
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 return map_.find(key) != map_.end();
51 6 }
52
53 private:
54 128028 void TouchLocked(const Key& key) {
55
1/2
✓ Branch 1 taken 128028 times.
✗ Branch 2 not taken.
128028 auto it = map_.find(key);
56
2/2
✓ Branch 2 taken 64002 times.
✓ Branch 3 taken 64026 times.
128028 if (it != map_.end()) {
57 64002 order_.splice(order_.begin(), order_, it->second);
58 64002 return;
59 }
60
1/2
✓ Branch 1 taken 64026 times.
✗ Branch 2 not taken.
64026 order_.push_front(key);
61
1/2
✓ Branch 2 taken 64026 times.
✗ Branch 3 not taken.
64026 map_[key] = order_.begin();
62 }
63
64 64022 void TrimToCapacityLocked() {
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64022 times.
64022 if (capacity_ == 0) {
66 ✗ map_.clear();
67 ✗ order_.clear();
68 ✗ return;
69 }
70
2/2
✓ Branch 1 taken 56618 times.
✓ Branch 2 taken 64022 times.
120640 while (order_.size() > capacity_) {
71 56618 const Key key = order_.back();
72 56618 order_.pop_back();
73
1/2
✓ Branch 1 taken 56618 times.
✗ Branch 2 not taken.
56618 map_.erase(key);
74 }
75 }
76
77 const size_t capacity_;
78 mutable std::mutex mutex_;
79 std::list<Key> order_;
80 std::unordered_map<Key, typename std::list<Key>::iterator> map_;
81 };
82