35 auto time_t = std::chrono::system_clock::to_time_t(tp);
36 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
37 tp.time_since_epoch()) % 1000;
41 localtime_s(&tm, &time_t);
43 localtime_r(&time_t, &tm);
46 std::ostringstream oss;
47 oss << std::put_time(&tm,
"%H:%M:%S")
48 <<
'.' << std::setfill(
'0') << std::setw(3) << ms.count();
56 std::cout <<
"=== Basic Time-Series Operations ===" << std::endl;
60 std::cout <<
"\n1. Creating time-series storage..." << std::endl;
70 if (ts_result.is_err()) {
71 std::cerr <<
" Failed to create time-series: "
72 << ts_result.error().message << std::endl;
76 auto ts = std::move(ts_result.value());
77 std::cout <<
" ✓ Created time-series: " << ts->name() << std::endl;
78 std::cout <<
" Retention: " << config.
retention_period.count() <<
"s" << std::endl;
79 std::cout <<
" Max points: " << config.
max_points << std::endl;
82 std::cout <<
"\n2. Writing metric data points..." << std::endl;
84 auto now = std::chrono::system_clock::now();
85 std::random_device rd;
86 std::mt19937 gen(rd());
87 std::uniform_real_distribution<> dis(30.0, 90.0);
90 for (
int i = 0; i < 100; ++i) {
91 auto timestamp = now - std::chrono::seconds(100 - i);
92 double cpu_value = dis(gen);
94 auto add_result = ts->add_point(cpu_value, timestamp);
95 if (add_result.is_err()) {
96 std::cerr <<
" Failed to add point: "
97 << add_result.error().message << std::endl;
101 std::cout <<
" ✓ Added 100 data points" << std::endl;
102 std::cout <<
" Current size: " << ts->size() <<
" points" << std::endl;
103 std::cout <<
" Memory footprint: " << ts->memory_footprint() <<
" bytes" << std::endl;
106 std::cout <<
"\n3. Retrieving latest value..." << std::endl;
108 auto latest_result = ts->get_latest_value();
109 if (latest_result.is_ok()) {
110 std::cout <<
" Latest CPU usage: "
111 << std::fixed << std::setprecision(2)
112 << latest_result.value() <<
"%" << std::endl;
116 std::cout <<
"\n4. Querying last 30 seconds..." << std::endl;
123 auto query_result = ts->query(query);
124 if (query_result.is_ok()) {
125 const auto& result = query_result.value();
126 std::cout <<
" ✓ Query returned " << result.points.size()
127 <<
" aggregated points" << std::endl;
128 std::cout <<
" Total samples: " << result.total_samples << std::endl;
129 std::cout <<
" Average value: "
130 << std::fixed << std::setprecision(2)
131 << result.get_average() <<
"%" << std::endl;
134 std::cout <<
"\n Sample points:" << std::endl;
135 for (
size_t i = 0; i < std::min(
size_t(3), result.points.size()); ++i) {
136 const auto& point = result.points[i];
138 << std::fixed << std::setprecision(2) << point.value <<
"%"
139 <<
" (samples: " << point.sample_count <<
")" << std::endl;
143 }
catch (
const std::exception& e) {
144 std::cerr <<
"Exception: " << e.what() << std::endl;
152 std::cout <<
"\n=== Aggregation Queries ===" << std::endl;
161 if (ts_result.is_err()) {
165 auto ts = std::move(ts_result.value());
168 std::cout <<
"\n1. Populating with response time data..." << std::endl;
170 auto now = std::chrono::system_clock::now();
171 std::random_device rd;
172 std::mt19937 gen(rd());
173 std::normal_distribution<> dis(100.0, 20.0);
175 for (
int i = 0; i < 500; ++i) {
176 auto timestamp = now - std::chrono::seconds(500 - i);
177 double response_time = std::max(10.0, dis(gen));
179 ts->add_point(response_time, timestamp);
182 std::cout <<
" ✓ Added 500 response time measurements" << std::endl;
185 std::cout <<
"\n2. Aggregation query (last 5 minutes)..." << std::endl;
192 auto query_result = ts->query(query);
193 if (query_result.is_ok()) {
194 const auto& result = query_result.value();
195 auto summary = result.get_summary();
197 std::cout <<
"\n Aggregation results:" << std::endl;
198 std::cout <<
" Count: " <<
summary.count << std::endl;
199 std::cout <<
" Average: "
200 << std::fixed << std::setprecision(2)
201 <<
summary.mean() <<
" ms" << std::endl;
202 std::cout <<
" Min: "
203 << std::fixed << std::setprecision(2)
204 <<
summary.min_value <<
" ms" << std::endl;
205 std::cout <<
" Max: "
206 << std::fixed << std::setprecision(2)
207 <<
summary.max_value <<
" ms" << std::endl;
208 std::cout <<
" Sum: "
209 << std::fixed << std::setprecision(2)
210 <<
summary.sum <<
" ms" << std::endl;
211 std::cout <<
" Rate of change: "
212 << std::fixed << std::setprecision(2)
213 << result.get_rate() <<
" ms/s" << std::endl;
216 }
catch (
const std::exception& e) {
217 std::cerr <<
"Exception: " << e.what() << std::endl;
225 std::cout <<
"\n=== Retention Policy & Downsampling ===" << std::endl;
228 std::cout <<
"\n1. Creating time-series with short retention..." << std::endl;
236 if (ts_result.is_err()) {
240 auto ts = std::move(ts_result.value());
241 std::cout <<
" ✓ Created time-series with 60-second retention" << std::endl;
244 std::cout <<
"\n2. Adding old data (beyond retention period)..." << std::endl;
246 auto now = std::chrono::system_clock::now();
249 for (
int i = 0; i < 60; ++i) {
250 auto old_timestamp = now - 120s + std::chrono::seconds(i);
251 ts->add_point(500.0 + i, old_timestamp);
255 for (
int i = 0; i < 60; ++i) {
256 auto recent_timestamp = now - 60s + std::chrono::seconds(i);
257 ts->add_point(800.0 + i, recent_timestamp);
260 std::cout <<
" Added 120 points total" << std::endl;
261 std::cout <<
" Current size after cleanup: " << ts->size() <<
" points" << std::endl;
262 std::cout <<
" (Old data beyond retention was automatically removed)" << std::endl;
265 std::cout <<
"\n3. Querying all retained data..." << std::endl;
272 auto query_result = ts->query(query);
273 if (query_result.is_ok()) {
274 const auto& result = query_result.value();
275 std::cout <<
" ✓ Retrieved " << result.points.size()
276 <<
" downsampled points (from " << result.total_samples
277 <<
" original samples)" << std::endl;
278 std::cout <<
" Downsampling ratio: "
279 << std::fixed << std::setprecision(1)
280 << (double)result.total_samples / result.points.size()
281 <<
"x compression" << std::endl;
284 }
catch (
const std::exception& e) {
285 std::cerr <<
"Exception: " << e.what() << std::endl;
293 std::cout <<
"\n=== Batch Point Operations ===" << std::endl;
296 std::cout <<
"\n1. Creating time-series..." << std::endl;
299 if (ts_result.is_err()) {
303 auto ts = std::move(ts_result.value());
306 std::cout <<
"\n2. Preparing batch of data points..." << std::endl;
308 std::vector<time_point_data> batch;
309 auto now = std::chrono::system_clock::now();
311 std::random_device rd;
312 std::mt19937 gen(rd());
313 std::uniform_real_distribution<> dis(50.0, 200.0);
315 for (
int i = 0; i < 200; ++i) {
316 auto timestamp = now - std::chrono::seconds(200 - i);
317 double throughput = dis(gen);
318 batch.emplace_back(timestamp, throughput);
321 std::cout <<
" ✓ Prepared " << batch.size() <<
" points" << std::endl;
324 std::cout <<
"\n3. Adding batch..." << std::endl;
326 auto add_result = ts->add_points(batch);
327 if (add_result.is_ok()) {
328 std::cout <<
" ✓ Batch insert successful" << std::endl;
329 std::cout <<
" Total points in series: " << ts->size() << std::endl;
330 std::cout <<
" Memory footprint: " << ts->memory_footprint() <<
" bytes" << std::endl;
333 }
catch (
const std::exception& e) {
334 std::cerr <<
"Exception: " << e.what() << std::endl;