Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::state_history_log Class Reference

#include <log.hpp>

Public Member Functions

 state_history_log (const char *const name, std::string log_filename, std::string index_filename, std::optional< state_history_log_prune_config > prune_conf=std::optional< state_history_log_prune_config >())
 
 ~state_history_log ()
 
uint32_t begin_block () const
 
uint32_t end_block () const
 
void read_header (state_history_log_header &header, bool assert_version=true)
 
void write_header (const state_history_log_header &header)
 
template<typename F >
void write_entry (state_history_log_header header, const chain::block_id_type &prev_id, F write_payload)
 
fc::cfileget_entry (uint32_t block_num, state_history_log_header &header)
 
chain::block_id_type get_block_id (uint32_t block_num)
 

Detailed Description

Definition at line 68 of file log.hpp.

Constructor & Destructor Documentation

◆ state_history_log()

sysio::state_history_log::state_history_log ( const char *const name,
std::string log_filename,
std::string index_filename,
std::optional< state_history_log_prune_config > prune_conf = std::optional<state_history_log_prune_config>() )
inline

Definition at line 82 of file log.hpp.

84 : name(name)
85 , log_filename(std::move(log_filename))
86 , index_filename(std::move(index_filename))
87 , prune_config(prune_conf) {
88 open_log();
89 open_index();
90
91 if(prune_config) {
92 SYS_ASSERT(prune_config->prune_blocks, chain::plugin_exception, "state history log prune configuration requires at least one block");
93 SYS_ASSERT(__builtin_popcount(prune_config->prune_threshold) == 1, chain::plugin_exception, "state history prune threshold must be power of 2");
94 //switch this over to the mask that will be used
95 prune_config->prune_threshold = ~(prune_config->prune_threshold-1);
96 }
97
98 //check for conversions to/from pruned log, as long as log contains something
99 if(_begin_block != _end_block) {
100 state_history_log_header first_header;
101 log.seek(0);
102 read_header(first_header);
103
104 if((is_ship_log_pruned(first_header.magic) == false) && prune_config) {
105 //need to convert non-pruned to pruned; first prune any ranges we can (might be none)
106 prune(fc::log_level::info);
107
108 //update first header to indicate prune feature is enabled
109 log.seek(0);
110 first_header.magic = ship_magic(get_ship_version(first_header.magic), ship_feature_pruned_log);
111 write_header(first_header);
112
113 //write trailer on log with num blocks
114 log.seek_end(0);
115 const uint32_t num_blocks_in_log = _end_block - _begin_block;
116 fc::raw::pack(log, num_blocks_in_log);
117 }
118 else if(is_ship_log_pruned(first_header.magic) && !prune_config) {
119 vacuum();
120 }
121 }
122 }
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
void read_header(state_history_log_header &header, bool assert_version=true)
Definition log.hpp:140
void write_header(const state_history_log_header &header)
Definition log.hpp:151
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
uint16_t get_ship_version(uint64_t magic)
Definition log.hpp:46
bool is_ship_log_pruned(uint64_t magic)
Definition log.hpp:51
uint64_t ship_magic(uint16_t version, uint16_t features=0)
Definition log.hpp:38
unsigned int uint32_t
Definition stdint.h:126
Here is the call graph for this function:

◆ ~state_history_log()

sysio::state_history_log::~state_history_log ( )
inline

Definition at line 124 of file log.hpp.

124 {
125 //nothing to do if log is empty or we aren't pruning
126 if(_begin_block == _end_block)
127 return;
128 if(!prune_config || !prune_config->vacuum_on_close)
129 return;
130
131 const size_t first_data_pos = get_pos(_begin_block);
132 const size_t last_data_pos = fc::file_size(log.get_file_path());
133 if(last_data_pos - first_data_pos < *prune_config->vacuum_on_close)
134 vacuum();
135 }
uint64_t file_size(const path &p)
Here is the call graph for this function:

Member Function Documentation

◆ begin_block()

uint32_t sysio::state_history_log::begin_block ( ) const
inline

Definition at line 137 of file log.hpp.

137{ return _begin_block; }

◆ end_block()

uint32_t sysio::state_history_log::end_block ( ) const
inline

Definition at line 138 of file log.hpp.

138{ return _end_block; }

◆ get_block_id()

chain::block_id_type sysio::state_history_log::get_block_id ( uint32_t block_num)
inline

Definition at line 219 of file log.hpp.

219 {
220 state_history_log_header header;
221 get_entry(block_num, header);
222 return header.block_id;
223 }
fc::cfile & get_entry(uint32_t block_num, state_history_log_header &header)
Definition log.hpp:211
Here is the call graph for this function:

◆ get_entry()

fc::cfile & sysio::state_history_log::get_entry ( uint32_t block_num,
state_history_log_header & header )
inline

Definition at line 211 of file log.hpp.

211 {
212 SYS_ASSERT(block_num >= _begin_block && block_num < _end_block, chain::plugin_exception,
213 "read non-existing block in ${name}.log", ("name", name));
214 log.seek(get_pos(block_num));
215 read_header(header);
216 return log;
217 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_header()

void sysio::state_history_log::read_header ( state_history_log_header & header,
bool assert_version = true )
inline

Definition at line 140 of file log.hpp.

140 {
141 char bytes[state_history_log_header_serial_size];
142 log.read(bytes, sizeof(bytes));
144 fc::raw::unpack(ds, header);
145 SYS_ASSERT(!ds.remaining(), chain::plugin_exception, "state_history_log_header_serial_size mismatch");
146 if (assert_version)
147 SYS_ASSERT(is_ship(header.magic) && is_ship_supported_version(header.magic), chain::plugin_exception,
148 "corrupt ${name}.log (0)", ("name", name));
149 }
static const Segment ds(Segment::ds)
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
vector< char > bytes
Definition types.hpp:243
bool is_ship_supported_version(uint64_t magic)
Definition log.hpp:48
bool is_ship(uint64_t magic)
Definition log.hpp:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ write_entry()

template<typename F >
void sysio::state_history_log::write_entry ( state_history_log_header header,
const chain::block_id_type & prev_id,
F write_payload )
inline

Definition at line 160 of file log.hpp.

160 {
161 auto block_num = chain::block_header::num_from_id(header.block_id);
162 SYS_ASSERT(_begin_block == _end_block || block_num <= _end_block, chain::plugin_exception,
163 "missed a block in ${name}.log", ("name", name));
164
165 if (_begin_block != _end_block && block_num > _begin_block) {
166 if (block_num == _end_block) {
167 SYS_ASSERT(prev_id == last_block_id, chain::plugin_exception, "missed a fork change in ${name}.log",
168 ("name", name));
169 } else {
170 state_history_log_header prev;
171 get_entry(block_num - 1, prev);
172 SYS_ASSERT(prev_id == prev.block_id, chain::plugin_exception, "missed a fork change in ${name}.log",
173 ("name", name));
174 }
175 }
176
177 if (block_num < _end_block)
178 truncate(block_num); //truncate is expected to always leave file pointer at the end
179 else if (!prune_config)
180 log.seek_end(0);
181 else if (prune_config && _begin_block != _end_block)
182 log.seek_end(-sizeof(uint32_t)); //overwrite the trailing block count marker on this write
183
184 //if we're operating on a pruned block log and this is the first entry in the log, make note of the feature in the header
185 if(prune_config && _begin_block == _end_block)
186 header.magic = ship_magic(get_ship_version(header.magic), ship_feature_pruned_log);
187
188 uint64_t pos = log.tellp();
189 write_header(header);
190 write_payload(log);
191 SYS_ASSERT(log.tellp() == pos + state_history_log_header_serial_size + header.payload_size, chain::plugin_exception,
192 "wrote payload with incorrect size to ${name}.log", ("name", name));
193 fc::raw::pack(log, pos);
194
195 fc::raw::pack(index, pos);
196 if (_begin_block == _end_block)
197 _index_begin_block = _begin_block = block_num;
198 _end_block = block_num + 1;
199 last_block_id = header.block_id;
200
201 if(prune_config) {
202 if((pos&prune_config->prune_threshold) != (log.tellp()&prune_config->prune_threshold))
204
205 const uint32_t num_blocks_in_log = _end_block - _begin_block;
206 fc::raw::pack(log, num_blocks_in_log);
207 }
208 }
unsigned __int64 uint64_t
Definition stdint.h:136
static uint32_t num_from_id(const block_id_type &id)
Here is the call graph for this function:

◆ write_header()

void sysio::state_history_log::write_header ( const state_history_log_header & header)
inline

Definition at line 151 of file log.hpp.

151 {
152 char bytes[state_history_log_header_serial_size];
154 fc::raw::pack(ds, header);
155 SYS_ASSERT(!ds.remaining(), chain::plugin_exception, "state_history_log_header_serial_size mismatch");
156 log.write(bytes, sizeof(bytes));
157 }
Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following file: