Joedb 9.1.4
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
merge.cpp
Go to the documentation of this file.
1#include "joedb/ui/merge.h"
3
4/////////////////////////////////////////////////////////////////////////////
5void joedb::merge(Database &merged, const Database &db)
6/////////////////////////////////////////////////////////////////////////////
7{
8 std::map<Table_Id, Record_Id> offset;
9
10 //
11 // First loop over tables to fill the offset map
12 //
13 for (const auto &[tid, tname]: merged.get_tables())
14 offset[tid] = merged.get_last_record_id(tid);
15
16 //
17 // Second loop to copy data, with added offset
18 //
19 for (const auto &[tid, tname]: merged.get_tables())
20 {
21 const Record_Id last_record_id = db.get_last_record_id(tid);
22 const Compact_Freedom_Keeper &freedom_keeper = db.get_freedom(tid);
23
24 if (last_record_id == Record_Id(0))
25 {
26 // do nothing, table is empty
27 }
28 else if (freedom_keeper.is_compact())
29 {
30 merged.insert_vector(tid, offset[tid] + 1, size_t(last_record_id));
31
32 for (const auto &[fid, fname]: db.get_fields(tid))
33 {
34 const Type &type = db.get_field_type(tid, fid);
35 size_t capacity;
36
37 switch (type.get_type_id())
38 {
39 case Type::Type_Id::null:
40 break;
41
42 #define TYPE_MACRO(type, return_type, type_id, R, W)\
43 case Type::Type_Id::type_id:\
44 {\
45 merged.update_vector_##type_id\
46 (\
47 tid,\
48 offset[tid] + 1,\
49 fid,\
50 size_t(last_record_id),\
51 db.get_own_##type_id##_const_storage(tid, Record_Id(1), fid, capacity)\
52 );\
53 }\
54 break;
55 #include "joedb/TYPE_MACRO.h"
56 }
57
58 if (type.get_type_id() == Type::Type_Id::reference)
59 {
60 const size_t reference_offset = size_t(offset[type.get_table_id()]);
61
62 Record_Id *reference = merged.get_own_reference_storage
63 (
64 tid,
65 offset[tid] + 1,
66 fid,
67 capacity
68 );
69
70 for (size_t i = 0; i < size_t(last_record_id); i++)
71 if (reference[i] != Record_Id(0))
72 reference[i] = reference[i] + reference_offset;
73 }
74 }
75 }
76 else
77 {
78 for (Record_Id record_id = Record_Id(1); size_t(record_id) <= size_t(last_record_id); ++record_id)
79 {
80 if (freedom_keeper.is_used(size_t(record_id) + 1))
81 {
82 const Record_Id merged_record_id = offset[tid] + size_t(record_id);
83 merged.insert_into(tid, merged_record_id);
84
85 for (const auto &[fid, fname]: db.get_fields(tid))
86 {
87 const Type &type = db.get_field_type(tid, fid);
88
89 switch (type.get_type_id())
90 {
91 case Type::Type_Id::null:
92 break;
93
94 case Type::Type_Id::reference:
95 {
96 Record_Id referenced = db.get_reference(tid, record_id, fid);
97 if (referenced != Record_Id(0))
98 referenced = referenced + size_t(offset[type.get_table_id()]);
99 merged.update_reference
100 (
101 tid,
102 merged_record_id,
103 fid,
104 referenced
105 );
106 }
107 break;
108
109 #define TYPE_MACRO(type, return_type, type_id, R, W)\
110 case Type::Type_Id::type_id:\
111 {\
112 merged.update_##type_id\
113 (\
114 tid,\
115 merged_record_id,\
116 fid,\
117 db.get_##type_id(tid, record_id, fid)\
118 );\
119 }\
120 break;
121 #define TYPE_MACRO_NO_REFERENCE
122 #include "joedb/TYPE_MACRO.h"
123 }
124 }
125 }
126 }
127 }
128 }
129}
bool is_used(size_t index) const
const Compact_Freedom_Keeper & get_freedom(Table_Id table_id) const override
const std::map< Table_Id, std::string > & get_tables() const override
const Type & get_field_type(Table_Id table_id, Field_Id field_id) const override
const std::map< Field_Id, std::string > & get_fields(Table_Id table_id) const override
void insert_into(Table_Id table_id, Record_Id record_id) final
Definition Database.cpp:9
void insert_vector(Table_Id table_id, Record_Id record_id, size_t size) final
Definition Database.cpp:27
Record_Id get_last_record_id(Table_Id table_id) const
Definition Readable.cpp:74
Table_Id get_table_id() const
Definition Type.h:41
Type_Id get_type_id() const
Definition Type.h:40
void merge(Database &merged, const Database &db)
Definition merge.cpp:5