]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/simple_cache.hpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / common / simple_cache.hpp
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#ifndef CEPH_SIMPLECACHE_H
16#define CEPH_SIMPLECACHE_H
17
f67539c2
TL
18#include <list>
19#include <map>
20#include <unordered_map>
21#include <utility>
22
11fdf7f2 23#include "common/ceph_mutex.h"
7c673cae
FG
24
25template <class K, class V, class C = std::less<K>, class H = std::hash<K> >
26class SimpleLRU {
11fdf7f2 27 ceph::mutex lock = ceph::make_mutex("SimpleLRU::lock");
7c673cae 28 size_t max_size;
eafe8130
TL
29 size_t max_bytes = 0;
30 size_t total_bytes = 0;
f67539c2
TL
31 std::unordered_map<K, typename std::list<std::pair<K, V>>::iterator, H> contents;
32 std::list<std::pair<K, V> > lru;
33 std::map<K, V, C> pinned;
7c673cae
FG
34
35 void trim_cache() {
b32b8144 36 while (contents.size() > max_size) {
7c673cae
FG
37 contents.erase(lru.back().first);
38 lru.pop_back();
39 }
40 }
41
eafe8130
TL
42 void trim_cache_bytes() {
43 while(total_bytes > max_bytes) {
44 total_bytes -= lru.back().second.length();
45 contents.erase(lru.back().first);
46 lru.pop_back();
47 }
48 }
49
7c673cae
FG
50 void _add(K key, V&& value) {
51 lru.emplace_front(key, std::move(value)); // can't move key because we access it below
52 contents[key] = lru.begin();
53 trim_cache();
54 }
55
eafe8130
TL
56 void _add_bytes(K key, V&& value) {
57 lru.emplace_front(key, std::move(value)); // can't move key because we access it below
58 contents[key] = lru.begin();
59 trim_cache_bytes();
60 }
61
7c673cae 62public:
11fdf7f2 63 SimpleLRU(size_t max_size) : max_size(max_size) {
7c673cae
FG
64 contents.rehash(max_size);
65 }
66
67 void pin(K key, V val) {
11fdf7f2 68 std::lock_guard l(lock);
7c673cae
FG
69 pinned.emplace(std::move(key), std::move(val));
70 }
71
72 void clear_pinned(K e) {
11fdf7f2 73 std::lock_guard l(lock);
f67539c2 74 for (auto i = pinned.begin();
7c673cae
FG
75 i != pinned.end() && i->first <= e;
76 pinned.erase(i++)) {
f67539c2 77 auto iter = contents.find(i->first);
7c673cae
FG
78 if (iter == contents.end())
79 _add(i->first, std::move(i->second));
80 else
81 lru.splice(lru.begin(), lru, iter->second);
82 }
83 }
84
85 void clear(K key) {
11fdf7f2 86 std::lock_guard l(lock);
f67539c2 87 auto i = contents.find(key);
7c673cae
FG
88 if (i == contents.end())
89 return;
eafe8130 90 total_bytes -= i->second->second.length();
7c673cae
FG
91 lru.erase(i->second);
92 contents.erase(i);
93 }
94
95 void set_size(size_t new_size) {
11fdf7f2 96 std::lock_guard l(lock);
7c673cae
FG
97 max_size = new_size;
98 trim_cache();
99 }
100
eafe8130
TL
101 size_t get_size() {
102 std::lock_guard l(lock);
103 return contents.size();
104 }
105
106 void set_bytes(size_t num_bytes) {
107 std::lock_guard l(lock);
108 max_bytes = num_bytes;
109 trim_cache_bytes();
110 }
111
112 size_t get_bytes() {
113 std::lock_guard l(lock);
114 return total_bytes;
115 }
116
7c673cae 117 bool lookup(K key, V *out) {
11fdf7f2 118 std::lock_guard l(lock);
f67539c2 119 auto i = contents.find(key);
7c673cae
FG
120 if (i != contents.end()) {
121 *out = i->second->second;
122 lru.splice(lru.begin(), lru, i->second);
123 return true;
124 }
f67539c2 125 auto i_pinned = pinned.find(key);
7c673cae
FG
126 if (i_pinned != pinned.end()) {
127 *out = i_pinned->second;
128 return true;
129 }
130 return false;
131 }
132
133 void add(K key, V value) {
11fdf7f2 134 std::lock_guard l(lock);
7c673cae
FG
135 _add(std::move(key), std::move(value));
136 }
eafe8130
TL
137
138 void add_bytes(K key, V value) {
139 std::lock_guard l(lock);
140 total_bytes += value.length();
141 _add_bytes(std::move(key), std::move(value));
142 }
7c673cae
FG
143};
144
145#endif