20 throw Exception(
"Cannot create Writable_Journal with read-only file");
22 else if (lock.is_creating_new())
38 if (lock.pos[0] != lock.pos[1] || lock.pos[2] != lock.pos[3])
93 const int64_t until_checkpoint
96 const int64_t source_checkpoint = std::min
98 journal.get_checkpoint_position(),
102 if (checkpoint_position < source_checkpoint)
104 const int64_t initial_position = get_position();
105 const int64_t initial_source_position = journal.get_position();
111 source_checkpoint - checkpoint_position
114 default_checkpoint();
116 set_position(initial_position);
117 journal.set_position(initial_source_position);
120 return checkpoint_position;
127 return file.get_position() - checkpoint_position;
136 ahead_of_checkpoint() > 0 ||
137 (ahead_of_checkpoint() == 0 && commit_level > current_commit_level)
142 checkpoint_index ^= 1;
143 checkpoint_position = file.get_position();
144 current_commit_level = commit_level;
147 file.exclusive_lock_head();
151 reinterpret_cast<const char *
>(&checkpoint_position),
152 sizeof(checkpoint_position),
154 int64_t(
sizeof(checkpoint_position)) * (2 * checkpoint_index)
158 file.flush_and_sync();
162 reinterpret_cast<const char *
>(&checkpoint_position),
163 sizeof(checkpoint_position),
165 int64_t(
sizeof(checkpoint_position)) * (2 * checkpoint_index + 1)
169 file.flush_and_sync();
174 file.set_position(checkpoint_position);
182 file.write<
operation_t>(operation_t::create_table);
183 file.write_string(name);
199 const std::string &name
202 file.write<
operation_t>(operation_t::rename_table);
204 file.write_string(name);
212 const std::string &name,
218 file.write_string(name);
220 if (type.get_type_id() == Type::Type_Id::reference)
243 const std::string &name
246 file.write<
operation_t>(operation_t::rename_field);
249 file.write_string(name);
257 file.write_string(name);
265 file.write_string(comment);
273 file.write<int64_t>(timestamp);
291 if (table_id == table_of_last_operation &&
292 record_id == record_of_last_operation + 1)
303 table_of_last_operation = table_id;
304 record_of_last_operation = record_id;
316 file.write<
operation_t>(operation_t::insert_vector);
319 file.compact_write<>(size);
321 table_of_last_operation = table_id;
322 record_of_last_operation = record_id;
339void joedb::Writable_Journal::generic_update
345 operation_t operation
350 table_id == table_of_last_operation &&
351 record_id == record_of_last_operation
355 int(operation_t::update_last_int8) -
356 int(operation_t::update_int8);
358 file.write<operation_t>(operation_t(
int(operation) + last));
360 field_of_last_update = field_id;
364 table_id == table_of_last_operation &&
365 record_id == record_of_last_operation + 1 &&
366 field_id == field_of_last_update
370 int(operation_t::update_next_int8) -
371 int(operation_t::update_int8);
372 file.write<operation_t>(operation_t(
int(operation) + next));
373 ++record_of_last_operation;
377 file.write<operation_t>(operation);
381 table_of_last_operation = table_id;
382 record_of_last_operation = record_id;
383 field_of_last_update = field_id;
388#define TYPE_MACRO(type, return_type, type_id, R, write_method)\
389void joedb::Writable_Journal::update_##type_id\
392 Record_Id record_id,\
397 generic_update(table_id, record_id, field_id, operation_t::update_##type_id);\
398 file.write_method(value);\
400void joedb::Writable_Journal::update_vector_##type_id\
403 Record_Id record_id,\
409 file.write<operation_t>(operation_t::update_vector_##type_id);\
410 file.compact_write<>(to_underlying(table_id));\
411 file.compact_write<>(to_underlying(record_id));\
412 file.compact_write<>(to_underlying(field_id));\
413 file.compact_write<>(size);\
414 table_of_last_operation = table_id;\
415 record_of_last_operation = record_id;\
416 field_of_last_update = field_id;\
420 Type::Type_Id::type_id == Type::Type_Id::blob ||\
421 Type::Type_Id::type_id == Type::Type_Id::string ||\
422 Type::Type_Id::type_id == Type::Type_Id::reference\
425 for (size_t i = 0; i < size; i++)\
426 file.write_method(value[i]);\
429 file.write_data((const char *)value, size * sizeof(type));\
437 const std::string &data
441 const int64_t blob_position = get_position();
442 file.compact_write<
size_t>(data.size());
444 file.sequential_write(data.data(), data.size());
445 return Blob(blob_position);
452 if (file.is_shared())
454 file.exclusive_lock_tail();
455 pull_without_locking();
463 if (file.is_shared())
471 if (ahead_of_checkpoint() > 0)
void set_position(int64_t position)
bool is_readonly() const noexcept
static void write(const char *message) noexcept
static constexpr uint32_t version_number
friend class Writable_Journal
static bool check_flag(Check check, Check flag)
static constexpr int64_t checkpoint_offset
int64_t checkpoint_position
static constexpr int64_t header_size
Blob write_blob_data(const std::string &data) final
int64_t ahead_of_checkpoint() const noexcept
~Writable_Journal() override
int64_t pull_from(Readonly_Journal &journal, int64_t until_checkpoint=std::numeric_limits< int64_t >::max())
void checkpoint(Commit_Level commit_level) final
constexpr std::underlying_type< Table_Id >::type to_underlying(Table_Id id)