Brenta Engine 1.2
Loading...
Searching...
No Matches
time_db.hpp
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#pragma once
7
8#include <typeindex>
9#include <typeinfo>
10#include <vector>
11#include <unordered_map>
12#include <memory>
13#include <cstdint>
14#include <concepts>
15#include <algorithm>
16
17namespace brenta
18{
19
20using TypeId = const void*;
21
22template<typename T>
23inline constexpr TypeId type_id = &type_id<T>;
24
25using TimeStamp = int64_t;
26
27template<typename T>
28concept TimeRow = requires(T r)
29{
30 requires std::same_as<
31 std::remove_cvref_t<decltype(r.timestamp)>,
32 TimeStamp
33 >;
34};
35
36//
37// TimeDB
38// ------
39//
40// Very simple time-series database.
41//
42class TimeDB
43{
44public:
45
46 struct ITable
47 {
48 virtual ~ITable() = default;
49 };
50
51 template<TimeRow Row>
52 class Table : public ITable
53 {
54 public:
55
56 void insert(Row row)
57 {
58 rows.push_back(std::move(row));
59 }
60
61 void remove(TimeStamp from, TimeStamp to)
62 {
63 rows.erase(std::remove_if(rows.begin(), rows.end(),
64 [&](const Row& r)
65 {
66 return r.timestamp >= from && r.timestamp <= to;
67 }),
68 rows.end());
69 }
70
71 std::vector<const Row*> range(TimeStamp from, TimeStamp to) const
72 {
73 std::vector<const Row*> result;
74
75 for (const auto& r : rows)
76 {
77 if (r.timestamp >= from && r.timestamp <= to)
78 result.push_back(&r);
79 }
80
81 return result;
82 }
83
84 template<typename Predicate>
85 std::vector<const Row*> query(Predicate pred) const
86 {
87 std::vector<const Row*> result;
88
89 for (const auto& r : rows)
90 {
91 if (pred(r))
92 result.push_back(&r);
93 }
94
95 return result;
96 }
97
98 private:
99
100 std::vector<Row> rows;
101 };
102
103 template<TimeRow Row>
104 void create_table()
105 {
106 TypeId id = type_id<Row>;
107
108 if (tables.contains(id))
109 return;
110
111 tables[id] = std::make_unique<Table<Row>>();
112 }
113
114 template<TimeRow Row>
115 void insert(Row row)
116 {
117 table<Row>().insert(std::move(row));
118 }
119
120 template<TimeRow Row>
121 void remove(TimeStamp from, TimeStamp to)
122 {
123 table<Row>().remove(from, to);
124 }
125
126 template<TimeRow Row>
127 std::vector<const Row*> range(TimeStamp from, TimeStamp to)
128 {
129 return table<Row>().range(from, to);
130 }
131
132 template<TimeRow Row, typename Predicate>
133 std::vector<const Row*> query(Predicate pred)
134 {
135 return table<Row>().query(pred);
136 }
137
138private:
139
140 template<TimeRow Row>
141 Table<Row>& table()
142 {
143 TypeId id = type_id<Row>;
144
145 auto it = tables.find(id);
146
147 if (it == tables.end())
148 {
149 auto tbl = std::make_unique<Table<Row>>();
150 auto* ptr = tbl.get();
151
152 tables[id] = std::move(tbl);
153
154 return *ptr;
155 }
156
157 return *static_cast<Table<Row>*>(it->second.get());
158 }
159
160private:
161
162 std::unordered_map<TypeId, std::unique_ptr<ITable>> tables;
163};
164
165} // namespace brenta