Skip to content

lru-cache #216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/features/client_http_sse_proxy.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "http_sse_proxy.h"
void HttpSseProxy::RegisterSseHandler() {
// 这里可以实现 SSE 接口注册逻辑,或转发 HTTP 请求到 LruCacheProxy
// 示例略。
}
7 changes: 7 additions & 0 deletions examples/features/client_http_sse_proxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once
#include "lru_cache_proxy.h"

class HttpSseProxy : public LruCacheProxy {
public:
void RegisterSseHandler(); // 可选:注册 SSE 接口到 Web Server
};
15 changes: 15 additions & 0 deletions examples/features/client_lru_cache_proxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include "proto/lru_cache.pb.h"
#include "proto/lru_cache.trpc.pb.h"
#include "trpc/client/service_proxy.h"

class LruCacheProxy : public trpc::ServiceProxy {
public:
using PutRequest = trpc::examples::lru::PutRequest;
using PutResponse = trpc::examples::lru::PutResponse;
using GetRequest = trpc::examples::lru::GetRequest;
using GetResponse = trpc::examples::lru::GetResponse;

TRPC_PROXY_METHOD(trpc::examples::lru::LruCacheService, Put, PutRequest, PutResponse)
TRPC_PROXY_METHOD(trpc::examples::lru::LruCacheService, Get, GetRequest, GetResponse)
};
25 changes: 25 additions & 0 deletions examples/features/lru_cache.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
syntax = "proto3";
package trpc.examples.lru;

service LruCacheService {
rpc Put (PutRequest) returns (PutResponse);
rpc Get (GetRequest) returns (GetResponse);
}

message PutRequest {
string key = 1;
bytes value = 2;
}

message PutResponse {
bool success = 1;
}

message GetRequest {
string key = 1;
}

message GetResponse {
bytes value = 1;
bool found = 2;
}
3 changes: 3 additions & 0 deletions examples/features/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
bazel build //examples/features/lru_cache/server:lru_cache_service
bazel-bin/examples/features/lru_cache/server/lru_cache_service
44 changes: 44 additions & 0 deletions examples/features/server_lru_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once
#include <list>
#include <unordered_map>
#include <mutex>
#include "trpc/util/fiber/fiber_mutex.h"

template<typename Key, typename Value, typename MutexType = std::mutex>
class LRUCache {
public:
explicit LRUCache(size_t capacity) : capacity_(capacity) {}

bool Put(const Key& key, const Value& value) {
std::lock_guard<MutexType> lock(mutex_);
auto it = cache_.find(key);
if (it != cache_.end()) {
items_.erase(it->second);
cache_.erase(it);
}
items_.emplace_front(key, value);
cache_[key] = items_.begin();
if (cache_.size() > capacity_) {
auto last = items_.end();
last--;
cache_.erase(last->first);
items_.pop_back();
}
return true;
}

bool Get(const Key& key, Value& value) {
std::lock_guard<MutexType> lock(mutex_);
auto it = cache_.find(key);
if (it == cache_.end()) return false;
value = it->second->second;
items_.splice(items_.begin(), items_, it->second);
return true;
}

private:
size_t capacity_;
std::list<std::pair<Key, Value>> items_;
std::unordered_map<Key, typename std::list<std::pair<Key, Value>>::iterator> cache_;
MutexType mutex_;
};
18 changes: 18 additions & 0 deletions examples/features/server_lru_cache_service.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "lru_cache_service.h"

trpc::Status LruCacheServiceImpl::Put(trpc::ServerContextPtr,
const trpc::examples::lru::PutRequest* request,
trpc::examples::lru::PutResponse* response) {
response->set_success(cache_.Put(request->key(), request->value()));
return trpc::kSuccStatus;
}

trpc::Status LruCacheServiceImpl::Get(trpc::ServerContextPtr,
const trpc::examples::lru::GetRequest* request,
trpc::examples::lru::GetResponse* response) {
std::string value;
bool found = cache_.Get(request->key(), value);
response->set_found(found);
if (found) response->set_value(value);
return trpc::kSuccStatus;
}
20 changes: 20 additions & 0 deletions examples/features/server_lru_cache_service.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
#include "proto/lru_cache.pb.h"
#include "proto/lru_cache.trpc.pb.h"
#include "lru_cache.h"

class LruCacheServiceImpl : public trpc::examples::lru::LruCacheService {
public:
LruCacheServiceImpl() : cache_(1000) {}

trpc::Status Put(trpc::ServerContextPtr context,
const trpc::examples::lru::PutRequest* request,
trpc::examples::lru::PutResponse* response) override;

trpc::Status Get(trpc::ServerContextPtr context,
const trpc::examples::lru::GetRequest* request,
trpc::examples::lru::GetResponse* response) override;

private:
LRUCache<std::string, std::string, trpc::FiberMutex> cache_;
};
13 changes: 13 additions & 0 deletions examples/features/test_lru_cache_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <gtest/gtest.h>
#include "server/lru_cache.h"

TEST(LruCacheTest, PutGetEvict) {
LRUCache<std::string, std::string> cache(2);
cache.Put("a", "1");
cache.Put("b", "2");
std::string v;
EXPECT_TRUE(cache.Get("a", v));
EXPECT_EQ(v, "1");
cache.Put("c", "3");
EXPECT_FALSE(cache.Get("b", v));
}