Joedb 9.5.0
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
dump.cpp
Go to the documentation of this file.
1#include "joedb/ui/dump.h"
3#include "joedb/Writable.h"
4
6#include "joedb/Multiplexer.h"
8
9namespace joedb
10{
11 /////////////////////////////////////////////////////////////////////////////
12 void dump(const Readable &db, Writable &writable, bool schema_only)
13 /////////////////////////////////////////////////////////////////////////////
14 {
15 //
16 // Dump tables
17 //
18 std::map<Table_Id, Table_Id> table_map;
19 {
20 Table_Id mapped_tid = Table_Id(0);
21 for (const auto &[tid, tname]: db.get_tables())
22 {
23 ++mapped_tid;
24 table_map[tid] = mapped_tid;
25 writable.create_table(tname);
26 }
27 }
28
29 //
30 // Dump fields
31 //
32 std::map<Table_Id, std::map<Field_Id, Field_Id>> field_maps;
33 {
34 for (const auto &[tid, tname]: db.get_tables())
35 {
36 Field_Id mapped_fid = Field_Id(0);
37 for (const auto &[fid, fname]: db.get_fields(tid))
38 {
39 ++mapped_fid;
40 Type type = db.get_field_type(tid, fid);
41 if (type.get_type_id() == Type::Type_Id::reference)
42 type = Type::reference(table_map[type.get_table_id()]);
43 field_maps[tid][fid] = mapped_fid;
44
45 writable.add_field(table_map[tid], fname, type);
46 }
47 }
48 }
49
50 //
51 // Dump records
52 //
53 if (schema_only)
54 return;
55
56 for (const auto &[tid, tname]: db.get_tables())
57 {
58 const Record_Id last_record_id = db.get_last_record_id(tid);
59
60 for (Record_Id record_id = Record_Id(1); record_id <= last_record_id;)
61 {
62 while
63 (
64 record_id <= last_record_id &&
65 !db.is_used(tid, record_id)
66 )
67 {
68 ++record_id;
69 }
70
71 size_t size = 0;
72
73 while
74 (
75 record_id + size <= last_record_id &&
76 db.is_used(tid, record_id + size)
77 )
78 {
79 size++;
80 }
81
82 if (size)
83 {
84 writable.insert_vector(table_map[tid], record_id, size);
85 record_id = record_id + size;
86 }
87 }
88
89 for (const auto &[fid, fname]: db.get_fields(tid))
90 {
91 for (Record_Id record_id{1}; record_id <= last_record_id; ++record_id)
92 {
93 if (db.is_used(tid, record_id))
94 {
95 Table_Id mapped_tid = table_map[tid];
96 Field_Id mapped_fid = field_maps[tid][fid];
97
98 switch (db.get_field_type(tid, fid).get_type_id())
99 {
101 break;
102
103 #define TYPE_MACRO(type, return_type, type_id, R, W)\
104 case Type::Type_Id::type_id:\
105 writable.update_##type_id\
106 (\
107 mapped_tid, record_id, mapped_fid, db.get_##type_id(tid, record_id, fid)\
108 );\
109 break;
110 #include "joedb/TYPE_MACRO.h"
111 }
112 }
113 }
114 }
115 }
116 }
117
118 /////////////////////////////////////////////////////////////////////////////
119 void dump_data(const Readable &db, Writable &writable)
120 /////////////////////////////////////////////////////////////////////////////
121 {
122 for (const auto &[tid, tname]: db.get_tables())
123 {
124 const Record_Id last_record_id = db.get_last_record_id(tid);
125
126 Record_Id record_id = Record_Id(1);
127
128 const Compact_Freedom_Keeper &freedom_keeper = db.get_freedom(tid);
129
130 while (record_id <= last_record_id)
131 {
132 while
133 (
134 record_id <= last_record_id &&
135 !freedom_keeper.is_used(to_underlying(record_id) + 1)
136 )
137 {
138 ++record_id;
139 }
140
141 size_t size = 0;
142
143 while
144 (
145 record_id + size <= last_record_id &&
146 freedom_keeper.is_used(to_underlying(record_id + size) + 1)
147 )
148 {
149 size++;
150 }
151
152 if (size > 1)
153 {
154 writable.insert_vector(tid, record_id, size);
155
156 for (const auto &[fid, fname]: db.get_fields(tid))
157 {
158 switch(db.get_field_type(tid, fid).get_type_id())
159 {
161 break;
162
163 #define TYPE_MACRO(type, return_type, type_id, R, W)\
164 case Type::Type_Id::type_id:\
165 {\
166 writable.update_vector_##type_id\
167 (\
168 tid,\
169 record_id,\
170 fid,\
171 size,\
172 &db.get_##type_id\
173 (\
174 tid,\
175 record_id,\
176 fid\
177 )\
178 );\
179 }\
180 break;
181 #include "joedb/TYPE_MACRO.h"
182 }
183 }
184 }
185 else if (size == 1)
186 {
187 writable.insert_into(tid, record_id);
188
189 for (const auto &[fid, fname]: db.get_fields(tid))
190 {
191 switch(db.get_field_type(tid, fid).get_type_id())
192 {
194 break;
195
196 #define TYPE_MACRO(type, return_type, type_id, R, W)\
197 case Type::Type_Id::type_id:\
198 {\
199 writable.update_##type_id\
200 (\
201 tid,\
202 record_id,\
203 fid,\
204 db.get_##type_id(tid, record_id, fid)\
205 );\
206 }\
207 break;
208 #include "joedb/TYPE_MACRO.h"
209 }
210 }
211 }
212
213 record_id = record_id + size;
214 }
215 }
216 writable.soft_checkpoint();
217 }
218
219 /////////////////////////////////////////////////////////////////////////////
220 void pack(Readonly_Journal &input_journal, Writable &writable)
221 /////////////////////////////////////////////////////////////////////////////
222 {
223 Database db;
224
225 {
227 Multiplexer multiplexer{db, schema_filter};
228
229 input_journal.replay_log(multiplexer);
230
231 if (schema_filter.has_blobs())
232 throw Exception("can't pack blobs");
233 }
234
235 dump_data(db, writable);
236 }
237}
bool is_used(ptrdiff_t index) const override
virtual const Type & get_field_type(Table_Id table_id, Field_Id field_id) const =0
bool is_used(Table_Id table_id, Record_Id record_id) const
Definition Readable.cpp:83
virtual const Compact_Freedom_Keeper & get_freedom(Table_Id table_id) const =0
virtual const std::map< Field_Id, std::string > & get_fields(Table_Id table_id) const =0
Record_Id get_last_record_id(Table_Id table_id) const
Definition Readable.cpp:74
virtual const std::map< Table_Id, std::string > & get_tables() const =0
void replay_log(Writable &writable)
static Type reference(Table_Id table_id)
Definition Type.h:52
Table_Id get_table_id() const
Definition Type.h:42
Type_Id get_type_id() const
Definition Type.h:41
virtual void insert_into(Table_Id table_id, Record_Id record_id)
Definition Writable.h:48
virtual void create_table(const std::string &name)
Definition Writable.h:24
virtual void insert_vector(Table_Id table_id, Record_Id record_id, size_t size)
Definition Writable.cpp:33
virtual void add_field(Table_Id table_id, const std::string &name, Type type)
Definition Writable.h:29
void soft_checkpoint()
Definition Writable.h:21
void pack(Readonly_Journal &input_journal, Writable &writable)
Definition dump.cpp:220
void dump(const Readable &db, Writable &writable, bool schema_only)
Definition dump.cpp:12
void dump_data(const Readable &db, Writable &writable)
Definition dump.cpp:119
Definition Blob.h:7
constexpr std::underlying_type< Table_Id >::type to_underlying(Table_Id id)
Definition index_types.h:21