|
|
|
@ -29,41 +29,18 @@ |
|
|
|
|
|
|
|
|
|
namespace tsi { |
|
|
|
|
|
|
|
|
|
static void cache_key_avl_destroy(void* /*key*/, void* /*unused*/) {} |
|
|
|
|
|
|
|
|
|
static void* cache_key_avl_copy(void* key, void* /*unused*/) { return key; } |
|
|
|
|
|
|
|
|
|
static long cache_key_avl_compare(void* key1, void* key2, void* /*unused*/) { |
|
|
|
|
return grpc_slice_cmp(*static_cast<grpc_slice*>(key1), |
|
|
|
|
*static_cast<grpc_slice*>(key2)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void cache_value_avl_destroy(void* /*value*/, void* /*unused*/) {} |
|
|
|
|
|
|
|
|
|
static void* cache_value_avl_copy(void* value, void* /*unused*/) { |
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// AVL only stores pointers, ownership belonges to the linked list.
|
|
|
|
|
static const grpc_avl_vtable cache_avl_vtable = { |
|
|
|
|
cache_key_avl_destroy, cache_key_avl_copy, cache_key_avl_compare, |
|
|
|
|
cache_value_avl_destroy, cache_value_avl_copy, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/// Node for single cached session.
|
|
|
|
|
class SslSessionLRUCache::Node { |
|
|
|
|
public: |
|
|
|
|
Node(const grpc_slice& key, SslSessionPtr session) : key_(key) { |
|
|
|
|
Node(const std::string& key, SslSessionPtr session) : key_(key) { |
|
|
|
|
SetSession(std::move(session)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~Node() { grpc_slice_unref_internal(key_); } |
|
|
|
|
|
|
|
|
|
// Not copyable nor movable.
|
|
|
|
|
Node(const Node&) = delete; |
|
|
|
|
Node& operator=(const Node&) = delete; |
|
|
|
|
|
|
|
|
|
void* AvlKey() { return &key_; } |
|
|
|
|
const std::string& key() const { return key_; } |
|
|
|
|
|
|
|
|
|
/// Returns a copy of the node's cache session.
|
|
|
|
|
SslSessionPtr CopySession() const { return session_->CopySession(); } |
|
|
|
@ -76,7 +53,7 @@ class SslSessionLRUCache::Node { |
|
|
|
|
private: |
|
|
|
|
friend class SslSessionLRUCache; |
|
|
|
|
|
|
|
|
|
grpc_slice key_; |
|
|
|
|
std::string key_; |
|
|
|
|
std::unique_ptr<SslCachedSession> session_; |
|
|
|
|
|
|
|
|
|
Node* next_ = nullptr; |
|
|
|
@ -85,7 +62,6 @@ class SslSessionLRUCache::Node { |
|
|
|
|
|
|
|
|
|
SslSessionLRUCache::SslSessionLRUCache(size_t capacity) : capacity_(capacity) { |
|
|
|
|
GPR_ASSERT(capacity > 0); |
|
|
|
|
entry_by_key_ = grpc_avl_create(&cache_avl_vtable); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SslSessionLRUCache::~SslSessionLRUCache() { |
|
|
|
@ -95,7 +71,6 @@ SslSessionLRUCache::~SslSessionLRUCache() { |
|
|
|
|
delete node; |
|
|
|
|
node = next; |
|
|
|
|
} |
|
|
|
|
grpc_avl_unref(entry_by_key_, nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size_t SslSessionLRUCache::Size() { |
|
|
|
@ -104,13 +79,12 @@ size_t SslSessionLRUCache::Size() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SslSessionLRUCache::Node* SslSessionLRUCache::FindLocked( |
|
|
|
|
const grpc_slice& key) { |
|
|
|
|
void* value = |
|
|
|
|
grpc_avl_get(entry_by_key_, const_cast<grpc_slice*>(&key), nullptr); |
|
|
|
|
if (value == nullptr) { |
|
|
|
|
const std::string& key) { |
|
|
|
|
auto it = entry_by_key_.find(key); |
|
|
|
|
if (it == entry_by_key_.end()) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
Node* node = static_cast<Node*>(value); |
|
|
|
|
Node* node = it->second; |
|
|
|
|
// Move to the beginning.
|
|
|
|
|
Remove(node); |
|
|
|
|
PushFront(node); |
|
|
|
@ -120,22 +94,21 @@ SslSessionLRUCache::Node* SslSessionLRUCache::FindLocked( |
|
|
|
|
|
|
|
|
|
void SslSessionLRUCache::Put(const char* key, SslSessionPtr session) { |
|
|
|
|
grpc_core::MutexLock lock(&lock_); |
|
|
|
|
Node* node = FindLocked(grpc_slice_from_static_string(key)); |
|
|
|
|
Node* node = FindLocked(key); |
|
|
|
|
if (node != nullptr) { |
|
|
|
|
node->SetSession(std::move(session)); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
grpc_slice key_slice = grpc_slice_from_copied_string(key); |
|
|
|
|
node = new Node(key_slice, std::move(session)); |
|
|
|
|
node = new Node(key, std::move(session)); |
|
|
|
|
PushFront(node); |
|
|
|
|
entry_by_key_ = grpc_avl_add(entry_by_key_, node->AvlKey(), node, nullptr); |
|
|
|
|
entry_by_key_.emplace(key, node); |
|
|
|
|
AssertInvariants(); |
|
|
|
|
if (use_order_list_size_ > capacity_) { |
|
|
|
|
GPR_ASSERT(use_order_list_tail_); |
|
|
|
|
node = use_order_list_tail_; |
|
|
|
|
Remove(node); |
|
|
|
|
// Order matters, key is destroyed after deleting node.
|
|
|
|
|
entry_by_key_ = grpc_avl_remove(entry_by_key_, node->AvlKey(), nullptr); |
|
|
|
|
entry_by_key_.erase(node->key()); |
|
|
|
|
delete node; |
|
|
|
|
AssertInvariants(); |
|
|
|
|
} |
|
|
|
@ -144,8 +117,7 @@ void SslSessionLRUCache::Put(const char* key, SslSessionPtr session) { |
|
|
|
|
SslSessionPtr SslSessionLRUCache::Get(const char* key) { |
|
|
|
|
grpc_core::MutexLock lock(&lock_); |
|
|
|
|
// Key is only used for lookups.
|
|
|
|
|
grpc_slice key_slice = grpc_slice_from_static_string(key); |
|
|
|
|
Node* node = FindLocked(key_slice); |
|
|
|
|
Node* node = FindLocked(key); |
|
|
|
|
if (node == nullptr) { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
@ -183,13 +155,6 @@ void SslSessionLRUCache::PushFront(SslSessionLRUCache::Node* node) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG |
|
|
|
|
static size_t calculate_tree_size(grpc_avl_node* node) { |
|
|
|
|
if (node == nullptr) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
return 1 + calculate_tree_size(node->left) + calculate_tree_size(node->right); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SslSessionLRUCache::AssertInvariants() { |
|
|
|
|
size_t size = 0; |
|
|
|
|
Node* prev = nullptr; |
|
|
|
@ -197,14 +162,15 @@ void SslSessionLRUCache::AssertInvariants() { |
|
|
|
|
while (current != nullptr) { |
|
|
|
|
size++; |
|
|
|
|
GPR_ASSERT(current->prev_ == prev); |
|
|
|
|
void* node = grpc_avl_get(entry_by_key_, current->AvlKey(), nullptr); |
|
|
|
|
GPR_ASSERT(node == current); |
|
|
|
|
auto it = entry_by_key_.find(current->key()); |
|
|
|
|
GPR_ASSERT(it != entry_by_key_.end()); |
|
|
|
|
GPR_ASSERT(it->second == current); |
|
|
|
|
prev = current; |
|
|
|
|
current = current->next_; |
|
|
|
|
} |
|
|
|
|
GPR_ASSERT(prev == use_order_list_tail_); |
|
|
|
|
GPR_ASSERT(size == use_order_list_size_); |
|
|
|
|
GPR_ASSERT(calculate_tree_size(entry_by_key_.root) == use_order_list_size_); |
|
|
|
|
GPR_ASSERT(entry_by_key_.size() == use_order_list_size_); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
void SslSessionLRUCache::AssertInvariants() {} |
|
|
|
|