-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathcache.cc
55 lines (48 loc) · 1.54 KB
/
cache.cc
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
#include "extensions/open_policy_agent/cache.h"
const uint64_t MAX_NUM_ENTRY = 1000;
namespace {
uint64_t computeHash(const Payload &payload) {
const uint64_t kMul = static_cast<uint64_t>(0x9ddfea08eb382d69);
uint64_t h = 0;
h += std::hash<std::string>()(payload.source_principal) * kMul;
h += std::hash<std::string>()(payload.destination_workload) * kMul;
h += std::hash<std::string>()(payload.request_method) * kMul;
h += std::hash<std::string>()(payload.request_url_path) * kMul;
return h;
}
} // namespace
bool ResultCache::check(const Payload ¶m, uint64_t &hash, bool &allowed,
uint64_t timestamp) {
hash = computeHash(param);
auto iter = result_cache_.find(hash);
if (iter == result_cache_.end()) {
return false;
}
const auto &entry = iter->second;
if (entry.second + valid_for_nanosec_ > timestamp) {
use(hash);
allowed = entry.first;
return true;
}
auto recent_iter = pos_.find(hash);
recent_.erase(recent_iter->second);
pos_.erase(hash);
result_cache_.erase(hash);
return false;
}
void ResultCache::add(const uint64_t hash, bool result, uint64_t timestamp) {
use(hash);
result_cache_.emplace(hash, std::make_pair(result, timestamp));
}
void ResultCache::use(const uint64_t hash) {
if (pos_.find(hash) != pos_.end()) {
recent_.erase(pos_[hash]);
} else if (recent_.size() >= MAX_NUM_ENTRY) {
int old = recent_.back();
recent_.pop_back();
result_cache_.erase(old);
pos_.erase(old);
}
recent_.push_front(hash);
pos_[hash] = recent_.begin();
}