Skip to content
Merged
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
63 changes: 33 additions & 30 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,69 +8,72 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories(include third_party)

set(PA_OVERRIDE ON)
set(PA_BUILD_TESTS OFF CACHE BOOL "Disable palloc tests for embedded pomai_cache" FORCE)
add_subdirectory(third_party/palloc)

add_library(pomai_cache_core
add_library(pomaicache SHARED
src/engine/engine.cpp
src/engine/ssd_store.cpp
src/policy/policies.cpp
src/server/http.cpp
src/server/ai_cache.cpp
src/pomai_embedded.cc
src/metrics/info_metrics.cpp
src/util/time.cpp
src/ds/bloom_filter.cpp
src/ds/count_min_sketch.cpp
src/ds/vector_index.cpp
src/ds/dep_graph.cpp
src/ds/compression.cpp
src/engine/prompt_cache.cpp
src/bindings/c_api.cc
)

target_link_libraries(pomai_cache_core PUBLIC palloc)

if(NOT WIN32)
add_executable(pomai_cache_server src/server/server_main.cpp)
target_link_libraries(pomai_cache_server PRIVATE pomai_cache_core uring)

add_executable(pomai_cache_cli apps/cli/main.cpp)

add_executable(pomai_cache_netbench bench/pomai_cache_netbench.cpp)
target_link_libraries(pomai_cache_netbench PRIVATE pomai_cache_core)
endif()

add_executable(pomai_cache_bench bench/pomai_cache_bench.cpp)
target_link_libraries(pomai_cache_bench PRIVATE pomai_cache_core)

add_executable(pomai_cache_ai_bench bench/ai_artifact_bench.cpp)
target_link_libraries(pomai_cache_ai_bench PRIVATE pomai_cache_core)

add_executable(pomai_cache_vector_bench bench/vector_cache_bench.cpp)
target_link_libraries(pomai_cache_vector_bench PRIVATE pomai_cache_core)
target_link_libraries(pomaicache PUBLIC palloc)

include(CTest)
if(BUILD_TESTING)
add_library(mini_catch_main third_party/catch2/catch_main.cpp)

add_executable(test_engine tests/test_engine.cpp)
target_link_libraries(test_engine PRIVATE pomai_cache_core mini_catch_main)

add_executable(test_http tests/test_http.cpp)
target_link_libraries(test_http PRIVATE pomai_cache_core mini_catch_main)
target_link_libraries(test_engine PRIVATE pomaicache mini_catch_main)

add_executable(test_ai_cache tests/test_ai_cache.cpp)
target_link_libraries(test_ai_cache PRIVATE pomai_cache_core mini_catch_main)
target_link_libraries(test_ai_cache PRIVATE pomaicache mini_catch_main)

add_test(NAME test_engine COMMAND test_engine)
add_test(NAME test_http COMMAND test_http)
add_test(NAME test_ai_cache COMMAND test_ai_cache)

if(NOT WIN32)
add_executable(test_integration tests/test_integration.cpp)
target_link_libraries(test_integration PRIVATE pomai_cache_core mini_catch_main)
target_link_libraries(test_integration PRIVATE pomaicache mini_catch_main)
add_test(NAME test_integration COMMAND test_integration)
endif()
endif()

if(NOT WIN32)
add_executable(pomai_cache_crash_harness tests/crash_harness.cpp)
target_link_libraries(pomai_cache_crash_harness PRIVATE pomai_cache_core)
target_link_libraries(pomai_cache_crash_harness PRIVATE pomaicache)

add_executable(pomai_cache_bench bench/pomai_cache_bench.cpp)
target_link_libraries(pomai_cache_bench PRIVATE pomaicache)

add_executable(ai_artifact_bench bench/ai_artifact_bench.cpp)
target_link_libraries(ai_artifact_bench PRIVATE pomaicache)

add_executable(vector_cache_bench bench/vector_cache_bench.cpp)
target_link_libraries(vector_cache_bench PRIVATE pomaicache)

add_executable(prompt_cache_bench bench/prompt_cache_bench.cpp)
target_link_libraries(prompt_cache_bench PRIVATE pomaicache)
endif()

option(BUILD_PYTHON_BINDINGS "Build Python bindings" ON)

if(BUILD_PYTHON_BINDINGS)
find_package(pybind11 CONFIG REQUIRED)
add_library(pomaicache_python MODULE src/bindings/python_bindings.cc)
target_link_libraries(pomaicache_python PRIVATE pomaicache pybind11::module)
set_target_properties(pomaicache_python PROPERTIES
OUTPUT_NAME "pomaicache"
)
endif()
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ BUILD_DIR ?= build
dev:
cmake -S . -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=Debug
cmake --build $(BUILD_DIR) -j
./$(BUILD_DIR)/pomai_cache_server --port 6379 --policy pomai_cost --params config/policy_params.json

release:
cmake -S . -B $(BUILD_DIR)-release -DCMAKE_BUILD_TYPE=Release
Expand All @@ -25,11 +24,9 @@ bench:
cmake -S . -B $(BUILD_DIR)-release -DCMAKE_BUILD_TYPE=Release
cmake --build $(BUILD_DIR)-release -j
./$(BUILD_DIR)-release/pomai_cache_bench

netbench:
cmake -S . -B $(BUILD_DIR)-release -DCMAKE_BUILD_TYPE=Release
cmake --build $(BUILD_DIR)-release -j
./$(BUILD_DIR)-release/pomai_cache_netbench
./$(BUILD_DIR)-release/ai_artifact_bench
./$(BUILD_DIR)-release/vector_cache_bench
./$(BUILD_DIR)-release/prompt_cache_bench

bench-all:
./scripts/bench_run.sh
Expand Down
129 changes: 53 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,87 +2,83 @@

<img src="./assets/logo.png"/>

Redis-compatible (subset) local cache core with RAM+SSD tiering, bounded TTL cleanup, crash-safe append-only SSD segments, selectable eviction policy (`lru`, `lfu`, `pomai_cost`), and an AI artifact cache layer for embeddings/prompts/RAG/rerank/response reuse.
Embedded local cache core with RAM+SSD tiering, bounded TTL cleanup, crash-safe append-only SSD segments, selectable eviction policy (`lru`, `lfu`, `pomai_cost`), and an AI artifact cache layer for embeddings/prompts/RAG/rerank/response reuse.

## Repo structure

- `src/server/` RESP parser + connection loop
- `src/engine/` KV store, TTL heap, memory limit enforcement
- `src/policy/` LRU, LFU, PomaiCostPolicy
- `src/metrics/` INFO metrics module
- `apps/cli/` simple CLI helper
- `bench/` benchmark tool
- `bindings/` C and Python embedded bindings
- `bench/` embedded benchmarks
- `tests/` correctness tests
- `tuner/` offline python tuner
- `docker/` container artifacts

## Quickstart
## Quickstart (embedded library)

### Build + run locally
### Build library

```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j
./build/pomai_cache_server --port 6379 --policy pomai_cost --params config/policy_params.json --ssd-enabled --data-dir ./data --ssd-value-min-bytes 2048 --fsync everysec
```

or:
This produces the shared library `libpomaicache` and optional Python module.

```bash
make dev
```
### C++ usage

### Run with Docker
```cpp
#include <pomaicache.h>

```bash
make docker-build
make docker-run
```
int main() {
pomaicache::Config cfg;
cfg.memory_limit_bytes = 128 * 1024 * 1024;
cfg.data_dir = "./data";

### Example redis-cli session
pomaicache::PomaiCache cache(cfg);
const std::string key = "demo";
const std::string value = "hello";

```bash
redis-cli -p 6379 SET demo hello EX 30
redis-cli -p 6379 GET demo
redis-cli -p 6379 INFO
redis-cli -p 6379 CONFIG GET POLICY
redis-cli -p 6379 CONFIG SET POLICY lru
redis-cli -p 6379 CONFIG SET PARAMS /app/config/policy_params.json
cache.Set(key, std::as_bytes(std::span(value.data(), value.size())),
pomaicache::Ttl{300000});

auto got = cache.Get(key);
if (got) {
// use *got
}
}
```

### C API usage

```c
#include <pomaicache_c.h>

int main() {
pomai_config_t cfg = { .memory_limit_bytes = 128 * 1024 * 1024,
.data_dir = "./data" };
pomai_t* db = pomai_create(&cfg);
const char* key = "demo";
const char* val = "hello";
pomai_set(db, key, strlen(key), val, strlen(val), 300000);
void* out = NULL;
size_t out_len = 0;
if (pomai_get(db, key, strlen(key), &out, &out_len) == 0) {
// use out / out_len
pomai_free(out);
}
pomai_destroy(db);
}
```

### AI artifact quickstart (redis-cli)
### Python usage

```bash
redis-cli -p 6379 AI.PUT embedding emb:modelA:hashA:768:float16 '{"artifact_type":"embedding","owner":"vector","schema_version":"v1","model_id":"modelA","snapshot_epoch":"ix1"}' "abc"
redis-cli -p 6379 AI.GET emb:modelA:hashA:768:float16
redis-cli -p 6379 AI.STATS
redis-cli -p 6379 AI.INVALIDATE EPOCH ix1
```
```python
import pomaicache

## Make targets

- `make dev` debug build + run server
- `make release` release build
- `make test` tests
- `make bench` benchmarks
- `make crash-suite` short crash/recovery harness
- `make fmt` clang-format
- `make docker-build`
- `make docker-run`

## Supported commands

- `GET`
- `SET key value [EX seconds] [OWNER owner_name]`
- `DEL key [key ...]`
- `EXPIRE key seconds`
- `TTL key`
- `MGET key [key ...]`
- `INFO`
- `CONFIG GET POLICY`
- `CONFIG SET POLICY <lru|lfu|pomai_cost>`
- `CONFIG SET PARAMS <path>`
cache = pomaicache.Cache(data_dir="./data", memory_limit_bytes=128*1024*1024)
# prompt_put / prompt_get APIs are available for prompt prefix caching
```

## Policy tuning

Expand All @@ -92,35 +88,16 @@ Generate params from offline stats snapshot:
python3 tuner/tune_policy.py --input stats_snapshot.json --output config/policy_params.json
```

The server loads params on startup and can reload at runtime via:

```bash
redis-cli -p 6379 CONFIG SET PARAMS /app/config/policy_params.json
```

Invalid/missing param files are handled safely with existing/default values.
Your application is responsible for loading updated params and calling the appropriate reload functions in the embedded API.

## Benchmarks

Run:

```bash
make bench
```

Bench reports per workload and policy:

- ops/s
- p50/p95/p99 latency
- hit rate
- memory used
Benchmarks under `bench/` exercise the embedded library in-process (no network).

## Security/stability constraints

- max key length enforced
- max value size enforced
- max concurrent connections enforced
- slow-client protection via bounded output buffer
- bounded per-tick TTL cleanup

## SSD tier defaults (laptop-safe)
Expand Down
38 changes: 0 additions & 38 deletions apps/cli/main.cpp

This file was deleted.

17 changes: 16 additions & 1 deletion bench/ai_artifact_bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ int main(int argc, char **argv) {
if (argc > 1)
out = argv[1];

std::cout << "Embedded AI artifact cache benchmark (in-process, no network)\n";

Engine e({64 * 1024 * 1024, 256, 4 * 1024 * 1024},
make_policy_by_name("pomai_cost"));
AiArtifactCache ai(e);
Expand Down Expand Up @@ -207,6 +209,19 @@ int main(int argc, char **argv) {
std::chrono::steady_clock::now() - r0)
.count();

// Human-readable summary.
std::cout << std::fixed << std::setprecision(2);
std::cout << "\nworkload ops/s p50_us p99_us hit_rate\n";
std::cout << "------------------------------------------------------------------\n";
for (const auto &r : results) {
std::cout << std::left << std::setw(22) << r.name << std::right
<< std::setw(10) << r.ops_s
<< std::setw(12) << r.p50
<< std::setw(12) << r.p99
<< std::setw(11) << r.hit_rate << "\n";
}
std::cout << "\nEngine constructor time (ms): " << warm_ms << "\n";

std::ofstream os(out);
os << "{\n \"workloads\": [\n";
for (std::size_t i = 0; i < results.size(); ++i) {
Expand All @@ -221,7 +236,7 @@ int main(int argc, char **argv) {
}
os << " ],\n";
os << " \"ssd_mb_s\": 0.0,\n";
os << " \"warm_restart_ms\": " << warm_ms << ",\n";
os << " \"engine_ctor_ms\": " << warm_ms << ",\n";
os << " \"dedup_ratio\": 0.0\n";
os << "}\n";

Expand Down
Loading
Loading