Skip to content

Commit 69d48af

Browse files
committed
feat(cache): add usage examples for cache module
1 parent 65e2302 commit 69d48af

File tree

5 files changed

+410
-0
lines changed

5 files changed

+410
-0
lines changed

examples/01_memory_cache_basic.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
*
3+
* @file 01_memory_cache_basic.cpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2025, Gaspard Kirira.
7+
* All rights reserved.
8+
* https://github.com/vixcpp/vix
9+
*
10+
* Use of this source code is governed by a MIT license
11+
* that can be found in the License file.
12+
*
13+
* Vix.cpp
14+
*
15+
*/
16+
// Run:
17+
// vix run examples/cache/01_memory_cache_basic.cpp
18+
19+
#include <chrono>
20+
#include <iostream>
21+
#include <memory>
22+
23+
#include <vix/cache/Cache.hpp>
24+
#include <vix/cache/CacheContext.hpp>
25+
#include <vix/cache/CacheEntry.hpp>
26+
#include <vix/cache/CachePolicy.hpp>
27+
#include <vix/cache/MemoryStore.hpp>
28+
29+
static std::int64_t now_ms()
30+
{
31+
using namespace std::chrono;
32+
return duration_cast<milliseconds>(
33+
steady_clock::now().time_since_epoch())
34+
.count();
35+
}
36+
37+
int main()
38+
{
39+
using namespace vix::cache;
40+
41+
auto store = std::make_shared<MemoryStore>();
42+
43+
CachePolicy policy;
44+
policy.ttl_ms = 5'000;
45+
46+
Cache cache(policy, store);
47+
48+
const std::string key = "GET /api/users?page=1";
49+
const auto t0 = now_ms();
50+
51+
CacheEntry entry;
52+
entry.status = 200;
53+
entry.body = R"({"users":[1,2,3]})";
54+
entry.headers["Content-Type"] = "application/json";
55+
entry.created_at_ms = t0;
56+
57+
cache.put(key, entry);
58+
59+
auto cached = cache.get(key, t0 + 100, CacheContext::Online());
60+
61+
if (!cached)
62+
{
63+
std::cout << "cache miss\n";
64+
return 1;
65+
}
66+
67+
std::cout << "cache hit\n";
68+
std::cout << "status: " << cached->status << "\n";
69+
std::cout << "body : " << cached->body << "\n";
70+
return 0;
71+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
*
3+
* @file 02_file_cache_persistence.cpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2025, Gaspard Kirira.
7+
* All rights reserved.
8+
* https://github.com/vixcpp/vix
9+
*
10+
* Use of this source code is governed by a MIT license
11+
* that can be found in the License file.
12+
*
13+
* Vix.cpp
14+
*
15+
*/
16+
// Run:
17+
// vix run examples/cache/02_file_cache_persistence.cpp
18+
19+
#include <chrono>
20+
#include <filesystem>
21+
#include <iostream>
22+
#include <memory>
23+
24+
#include <vix/cache/Cache.hpp>
25+
#include <vix/cache/CacheContext.hpp>
26+
#include <vix/cache/CacheEntry.hpp>
27+
#include <vix/cache/CachePolicy.hpp>
28+
#include <vix/cache/FileStore.hpp>
29+
30+
static std::int64_t now_ms()
31+
{
32+
using namespace std::chrono;
33+
return duration_cast<std::chrono::milliseconds>(
34+
std::chrono::steady_clock::now().time_since_epoch())
35+
.count();
36+
}
37+
38+
int main()
39+
{
40+
using namespace vix::cache;
41+
42+
const std::filesystem::path file = "./build/examples/cache/cache_http.json";
43+
44+
{
45+
auto store = std::make_shared<FileStore>(FileStore::Config{
46+
.file_path = file,
47+
.pretty_json = true});
48+
49+
CachePolicy policy;
50+
policy.ttl_ms = 10'000;
51+
52+
Cache cache(policy, store);
53+
54+
CacheEntry entry;
55+
entry.status = 200;
56+
entry.body = R"({"source":"disk"})";
57+
entry.headers["Content-Type"] = "application/json";
58+
entry.created_at_ms = now_ms();
59+
60+
cache.put("GET /api/products?limit=3", entry);
61+
62+
std::cout << "entry written to disk\n";
63+
}
64+
65+
{
66+
auto store = std::make_shared<FileStore>(FileStore::Config{
67+
.file_path = file,
68+
.pretty_json = false});
69+
70+
CachePolicy policy;
71+
policy.ttl_ms = 10'000;
72+
73+
Cache cache(policy, store);
74+
75+
auto cached = cache.get(
76+
"GET /api/products?limit=3",
77+
now_ms() + 100,
78+
CacheContext::Online());
79+
80+
if (!cached)
81+
{
82+
std::cout << "cache miss after reload\n";
83+
return 1;
84+
}
85+
86+
std::cout << "cache hit after reload\n";
87+
std::cout << "body: " << cached->body << "\n";
88+
}
89+
90+
return 0;
91+
}

examples/03_lru_cache_eviction.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
*
3+
* @file 03_lru_cache_eviction.cpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2025, Gaspard Kirira.
7+
* All rights reserved.
8+
* https://github.com/vixcpp/vix
9+
*
10+
* Use of this source code is governed by a MIT license
11+
* that can be found in the License file.
12+
*
13+
* Vix.cpp
14+
*
15+
*/
16+
// Run:
17+
// vix run examples/cache/03_lru_cache_eviction.cpp
18+
19+
#include <chrono>
20+
#include <iostream>
21+
#include <memory>
22+
23+
#include <vix/cache/Cache.hpp>
24+
#include <vix/cache/CacheContext.hpp>
25+
#include <vix/cache/CacheEntry.hpp>
26+
#include <vix/cache/CachePolicy.hpp>
27+
#include <vix/cache/LruMemoryStore.hpp>
28+
29+
static std::int64_t now_ms()
30+
{
31+
using namespace std::chrono;
32+
return duration_cast<milliseconds>(
33+
steady_clock::now().time_since_epoch())
34+
.count();
35+
}
36+
37+
static vix::cache::CacheEntry make_entry(
38+
const std::string &body,
39+
std::int64_t t)
40+
{
41+
vix::cache::CacheEntry e;
42+
e.status = 200;
43+
e.body = body;
44+
e.created_at_ms = t;
45+
return e;
46+
}
47+
48+
int main()
49+
{
50+
using namespace vix::cache;
51+
52+
auto store = std::make_shared<LruMemoryStore>(
53+
LruMemoryStore::Config{.max_entries = 2});
54+
55+
CachePolicy policy;
56+
policy.ttl_ms = 10'000;
57+
58+
Cache cache(policy, store);
59+
60+
const auto t0 = now_ms();
61+
62+
cache.put("k1", make_entry("A", t0));
63+
cache.put("k2", make_entry("B", t0));
64+
65+
// Touch k1 -> k2 becomes least recently used
66+
(void)cache.get("k1", t0 + 1, CacheContext::Online());
67+
68+
cache.put("k3", make_entry("C", t0 + 2));
69+
70+
auto k1 = cache.get("k1", t0 + 3, CacheContext::Online());
71+
auto k2 = cache.get("k2", t0 + 3, CacheContext::Online());
72+
auto k3 = cache.get("k3", t0 + 3, CacheContext::Online());
73+
74+
std::cout << "k1: " << (k1 ? "present" : "missing") << "\n";
75+
std::cout << "k2: " << (k2 ? "present" : "missing") << "\n";
76+
std::cout << "k3: " << (k3 ? "present" : "missing") << "\n";
77+
78+
return 0;
79+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
*
3+
* @file 04_offline_and_network_error.cpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2025, Gaspard Kirira.
7+
* All rights reserved.
8+
* https://github.com/vixcpp/vix
9+
*
10+
* Use of this source code is governed by a MIT license
11+
* that can be found in the License file.
12+
*
13+
* Vix.cpp
14+
*
15+
*/
16+
// Run:
17+
// vix run examples/cache/04_offline_and_network_error.cpp
18+
19+
#include <chrono>
20+
#include <iostream>
21+
#include <memory>
22+
23+
#include <vix/cache/Cache.hpp>
24+
#include <vix/cache/CacheContext.hpp>
25+
#include <vix/cache/CacheEntry.hpp>
26+
#include <vix/cache/CachePolicy.hpp>
27+
#include <vix/cache/MemoryStore.hpp>
28+
29+
static std::int64_t now_ms()
30+
{
31+
using namespace std::chrono;
32+
return duration_cast<milliseconds>(
33+
steady_clock::now().time_since_epoch())
34+
.count();
35+
}
36+
37+
int main()
38+
{
39+
using namespace vix::cache;
40+
41+
auto store = std::make_shared<MemoryStore>();
42+
43+
CachePolicy policy;
44+
policy.ttl_ms = 100;
45+
policy.allow_stale_if_offline = true;
46+
policy.stale_if_offline_ms = 10'000;
47+
policy.allow_stale_if_error = true;
48+
policy.stale_if_error_ms = 5'000;
49+
50+
Cache cache(policy, store);
51+
52+
const auto t0 = now_ms();
53+
54+
CacheEntry entry;
55+
entry.status = 200;
56+
entry.body = R"({"cached":true})";
57+
entry.created_at_ms = t0;
58+
59+
cache.put("GET /api/profile", entry);
60+
61+
{
62+
auto fresh = cache.get("GET /api/profile", t0 + 50, CacheContext::Online());
63+
std::cout << "fresh online: " << (fresh ? "hit" : "miss") << "\n";
64+
}
65+
66+
{
67+
auto offline_stale = cache.get("GET /api/profile", t0 + 3000, CacheContext::Offline());
68+
std::cout << "offline stale: " << (offline_stale ? "hit" : "miss") << "\n";
69+
}
70+
71+
{
72+
auto error_stale = cache.get("GET /api/profile", t0 + 4000, CacheContext::NetworkError());
73+
std::cout << "network error stale: " << (error_stale ? "hit" : "miss") << "\n";
74+
}
75+
76+
{
77+
auto too_old = cache.get("GET /api/profile", t0 + 20'000, CacheContext::Offline());
78+
std::cout << "too old offline: " << (too_old ? "hit" : "miss") << "\n";
79+
}
80+
81+
return 0;
82+
}

0 commit comments

Comments
 (0)