1#include <iostream>
2#include <cstring>
3#include <thread>
4#include <pcg_random.hpp>
5#include <Common/ArrayCache.h>
6#include <IO/ReadHelpers.h>
7
8
9template <typename Cache>
10void printStats(const Cache & cache)
11{
12 typename Cache::Statistics statistics = cache.getStatistics();
13 std::cerr
14 << "total_chunks_size: " << statistics.total_chunks_size << "\n"
15 << "total_allocated_size: " << statistics.total_allocated_size << "\n"
16 << "total_size_currently_initialized: " << statistics.total_size_currently_initialized << "\n"
17 << "total_size_in_use: " << statistics.total_size_in_use << "\n"
18 << "num_chunks: " << statistics.num_chunks << "\n"
19 << "num_regions: " << statistics.num_regions << "\n"
20 << "num_free_regions: " << statistics.num_free_regions << "\n"
21 << "num_regions_in_use: " << statistics.num_regions_in_use << "\n"
22 << "num_keyed_regions: " << statistics.num_keyed_regions << "\n"
23 << "hits: " << statistics.hits << "\n"
24 << "concurrent_hits: " << statistics.concurrent_hits << "\n"
25 << "misses: " << statistics.misses << "\n"
26 << "allocations: " << statistics.allocations << "\n"
27 << "allocated_bytes: " << statistics.allocated_bytes << "\n"
28 << "evictions: " << statistics.evictions << "\n"
29 << "evicted_bytes: " << statistics.evicted_bytes << "\n"
30 << "secondary_evictions: " << statistics.secondary_evictions << "\n"
31 << "\n";
32}
33
34/** Example:
35 * time ./array_cache 68000000 1 10000000 2000000 200
36 */
37
38
39int main(int argc, char ** argv)
40{
41 if (argc < 6)
42 {
43 std::cerr << "Usage: program cache_size num_threads num_iterations region_max_size max_key\n";
44 return 1;
45 }
46
47 size_t cache_size = DB::parse<size_t>(argv[1]);
48 size_t num_threads = DB::parse<size_t>(argv[2]);
49 size_t num_iterations = DB::parse<size_t>(argv[3]);
50 size_t region_max_size = DB::parse<size_t>(argv[4]);
51 size_t max_key = DB::parse<size_t>(argv[5]);
52
53 using Cache = ArrayCache<int, int>;
54 Cache cache(cache_size);
55
56 std::vector<std::thread> threads;
57 for (size_t i = 0; i < num_threads; ++i)
58 {
59 threads.emplace_back([&]
60 {
61 pcg64 generator(randomSeed());
62
63 for (size_t j = 0; j < num_iterations; ++j)
64 {
65 size_t size = std::uniform_int_distribution<size_t>(1, region_max_size)(generator);
66 int key = std::uniform_int_distribution<int>(1, max_key)(generator);
67
68 cache.getOrSet(
69 key,
70 [=]{ return size; },
71 [=](void * /*ptr*/, int & payload)
72 {
73 payload = j;
74 // memset(ptr, j, size);
75 },
76 nullptr);
77
78 // printStats(cache);
79 }
80 });
81 }
82
83 std::atomic_bool stop{};
84
85 std::thread stats_thread([&]
86 {
87 while (!stop)
88 {
89 usleep(100000);
90 printStats(cache);
91 }
92 });
93
94 for (auto & thread : threads)
95 thread.join();
96
97 stop = true;
98 stats_thread.join();
99
100 return 0;
101
102/*
103 using Cache = ArrayCache<int, int>;
104 Cache cache(64 * 1024 * 1024);
105
106 cache.getOrSet(
107 1,
108 [=]{ return 32 * 1024 * 1024; },
109 [=](void * ptr, int & payload)
110 {
111 payload = 1;
112 },
113 nullptr);
114
115 printStats(cache);
116
117 cache.getOrSet(
118 2,
119 [=]{ return 32 * 1024 * 1024; },
120 [=](void * ptr, int & payload)
121 {
122 payload = 2;
123 },
124 nullptr);
125
126 printStats(cache);
127
128 cache.getOrSet(
129 3,
130 [=]{ return 32 * 1024 * 1024; },
131 [=](void * ptr, int & payload)
132 {
133 payload = 3;
134 },
135 nullptr);
136
137 printStats(cache);*/
138}
139