1
0
mirror of https://github.com/danog/ton.git synced 2024-12-02 17:38:33 +01:00
ton/tddb/td/db/binlog/Binlog.h
2019-09-07 14:33:36 +04:00

136 lines
3.5 KiB
C++

/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
*/
#pragma once
#include "BinlogReaderInterface.h"
#include "td/db/utils/FileSyncState.h"
#include "td/db/utils/StreamInterface.h"
#include "td/actor/actor.h"
#include "td/utils/misc.h"
#include "td/utils/port/FileFd.h"
namespace td {
class BinlogReaderInterface;
class StreamToFileActor;
namespace detail {
class FlushHelperActor;
} // namespace detail
class Binlog {
public:
explicit Binlog(string path);
Status replay_sync(BinlogReaderInterface& binlog_reader);
void replay_async(std::shared_ptr<BinlogReaderInterface> binlog_reader, Promise<Unit> promise);
static void destroy(CSlice path);
void destroy();
private:
string path_;
};
class BinlogWriter {
public:
BinlogWriter(std::string path);
Status open();
template <class EventT>
Status write_event(EventT&& event, BinlogReaderInterface* binlog_reader);
Status lazy_flush();
Status flush();
Status sync();
Status close();
private:
string path_;
FileFd fd_;
StreamReader buf_reader_;
StreamWriter buf_writer_;
};
class BinlogWriterAsync {
public:
BinlogWriterAsync(std::string path);
~BinlogWriterAsync();
Status open();
template <class EventT>
Status write_event(EventT&& event, BinlogReaderInterface* binlog_reader);
void close(Promise<> promise);
void lazy_flush();
void flush();
void sync(Promise<Unit> promise = {});
private:
std::string path_;
StreamWriter buf_writer_;
actor::ActorId<StreamToFileActor> writer_actor_;
actor::ActorOwn<detail::FlushHelperActor> flush_helper_actor_;
FileSyncState::Reader sync_state_reader_;
};
template <class EventT>
Status BinlogWriter::write_event(EventT&& event, BinlogReaderInterface* binlog_reader) {
int64 need_size = -event.serialize({});
auto dest =
buf_writer_.prepare_write_at_least(narrow_cast<size_t>(need_size)).truncate(narrow_cast<size_t>(need_size));
auto written = event.serialize(dest);
CHECK(written == need_size);
if (binlog_reader != nullptr) {
TRY_RESULT(parsed, binlog_reader->parse(dest));
binlog_reader->flush();
CHECK(parsed == written);
}
buf_writer_.confirm_write(narrow_cast<size_t>(written));
return lazy_flush();
}
template <class EventT>
Status BinlogWriterAsync::write_event(EventT&& event, BinlogReaderInterface* binlog_reader) {
int64 need_size = -event.serialize({});
auto dest =
buf_writer_.prepare_write_at_least(narrow_cast<size_t>(need_size)).truncate(narrow_cast<size_t>(need_size));
auto written = event.serialize(dest);
CHECK(written == need_size);
if (binlog_reader != nullptr) {
TRY_RESULT(parsed, binlog_reader->parse(dest));
CHECK(parsed == written);
}
buf_writer_.confirm_write(narrow_cast<size_t>(written));
lazy_flush();
return Status::OK();
}
} // namespace td