-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLRUCache.cpp
84 lines (70 loc) · 1.81 KB
/
LRUCache.cpp
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
#include "./LRUCache.hpp"
#include <cstring>
LRUCache::LRUCache(size_t cap) : capacity(cap) {}
LRUCache::~LRUCache()
{
for (auto elem : cache_list)
{
free(elem->data);
free(elem->url);
delete elem;
}
}
cache_element *LRUCache::find(const char *url)
{
std::lock_guard<std::mutex> lock(cache_mutex);
auto it = cache_map.find(url);
if (it == cache_map.end())
return nullptr;
moveToFront(it->second);
(*it->second)->lru_time_track = time(nullptr);
return *it->second;
}
void LRUCache::add(const char *url, const char *data, int len)
{
std::lock_guard<std::mutex> lock(cache_mutex);
auto it = cache_map.find(url);
if (it != cache_map.end())
{
moveToFront(it->second);
return;
}
if (cache_list.size() >= capacity)
{
evict();
}
cache_element *new_element = new cache_element;
new_element->url = strdup(url);
new_element->data = (char *)malloc(len);
memcpy(new_element->data, data, len);
new_element->len = len;
new_element->lru_time_track = time(nullptr);
cache_list.push_front(new_element);
cache_map[url] = cache_list.begin();
}
void LRUCache::remove(const char *url)
{
std::lock_guard<std::mutex> lock(cache_mutex);
auto it = cache_map.find(url);
if (it == cache_map.end())
return;
cache_element *elem = *it->second;
cache_list.erase(it->second);
cache_map.erase(it);
free(elem->data);
free(elem->url);
delete elem;
}
void LRUCache::moveToFront(std::list<cache_element *>::iterator it)
{
cache_list.splice(cache_list.begin(), cache_list, it);
}
void LRUCache::evict()
{
cache_element *elem = cache_list.back();
cache_map.erase(elem->url);
cache_list.pop_back();
free(elem->data);
free(elem->url);
delete elem;
}