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

#include <store_provider.hpp>

Collaboration diagram for sysio::trace_api::store_provider:

Public Types

using open_state = slice_directory::open_state
 

Public Member Functions

 store_provider (const boost::filesystem::path &slice_dir, uint32_t stride_width, std::optional< uint32_t > minimum_irreversible_history_blocks, std::optional< uint32_t > minimum_uncompressed_irreversible_history_blocks, size_t compression_seek_point_stride)
 
template<typename BlockTrace >
void append (const BlockTrace &bt)
 
void append_lib (uint32_t lib)
 
void append_trx_ids (block_trxs_entry tt)
 
get_block_t get_block (uint32_t block_height, const yield_function &yield={})
 
get_block_n get_trx_block_number (const chain::transaction_id_type &trx_id, std::optional< uint32_t > minimum_irreversible_history_blocks, const yield_function &yield={})
 
void start_maintenance_thread (log_handler log)
 
void stop_maintenance_thread ()
 

Protected Member Functions

template<typename Fn >
uint64_t scan_metadata_log_from (uint32_t block_height, uint64_t offset, Fn &&fn, const yield_function &yield)
 
std::optional< data_log_entryread_data_log (uint32_t block_height, uint64_t offset)
 
void initialize_new_index_slice_file (fc::cfile &index)
 
void validate_existing_index_slice_file (fc::cfile &index, open_state state)
 

Protected Attributes

slice_directory _slice_directory
 

Detailed Description

Provides read and write access to block trace data.

Definition at line 264 of file store_provider.hpp.

Member Typedef Documentation

◆ open_state

Constructor & Destructor Documentation

◆ store_provider()

sysio::trace_api::store_provider::store_provider ( const boost::filesystem::path & slice_dir,
uint32_t stride_width,
std::optional< uint32_t > minimum_irreversible_history_blocks,
std::optional< uint32_t > minimum_uncompressed_irreversible_history_blocks,
size_t compression_seek_point_stride )

Definition at line 34 of file store_provider.cpp.

36 : _slice_directory(slice_dir, stride_width, minimum_irreversible_history_blocks, minimum_uncompressed_irreversible_history_blocks, compression_seek_point_stride) {
37 }

Member Function Documentation

◆ append()

template<typename BlockTrace >
template void sysio::trace_api::store_provider::append< block_trace_v2 > ( const BlockTrace & bt)

Definition at line 40 of file store_provider.cpp.

40 {
41 fc::cfile trace;
42 fc::cfile index;
43 const uint32_t slice_number = _slice_directory.slice_number(bt.number);
44 _slice_directory.find_or_create_slice_pair(slice_number, open_state::write, trace, index);
45 // storing as static_variant to allow adding other data types to the trace file in the future
46 const uint64_t offset = append_store(data_log_entry { bt }, trace);
47
48 auto be = metadata_log_entry { block_entry_v0 { .id = bt.id, .number = bt.number, .offset = offset }};
49 append_store(be, index);
50 }
uint32_t slice_number(uint32_t block_height) const
void find_or_create_slice_pair(uint32_t slice_number, open_state state, fc::cfile &trace, fc::cfile &index)
std::variant< block_entry_v0, lib_entry_v0, block_trxs_entry > metadata_log_entry
std::variant< block_trace_v0, block_trace_v1, block_trace_v2 > data_log_entry
Definition data_log.hpp:9
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
void bt(const Operand &op, const Reg &reg)
Here is the call graph for this function:

◆ append_lib()

void sysio::trace_api::store_provider::append_lib ( uint32_t lib)

Definition at line 55 of file store_provider.cpp.

55 {
56 fc::cfile index, trx_id;
57 const uint32_t slice_number = _slice_directory.slice_number(lib);
58 _slice_directory.find_or_create_index_slice(slice_number, open_state::write, index);
59 auto le = metadata_log_entry { lib_entry_v0 { .lib = lib }};
60 append_store(le, index);
61 _slice_directory.find_or_create_trx_id_slice(slice_number, open_state::write, trx_id);
62 append_store(le, trx_id);
64 }
bool find_or_create_index_slice(uint32_t slice_number, open_state state, fc::cfile &index_file) const
bool find_or_create_trx_id_slice(uint32_t slice_number, open_state state, fc::cfile &trx_id_file) const
Here is the call graph for this function:

◆ append_trx_ids()

void sysio::trace_api::store_provider::append_trx_ids ( block_trxs_entry tt)

Definition at line 66 of file store_provider.cpp.

66 {
67 fc::cfile trx_id_file;
68 const uint32_t slice_number = _slice_directory.slice_number(tt.block_num);
69 _slice_directory.find_or_create_trx_id_slice(slice_number, open_state::write, trx_id_file);
70 auto entry = metadata_log_entry { std::move(tt) };
71 append_store(entry, trx_id_file);
72 }
Here is the call graph for this function:

◆ get_block()

get_block_t sysio::trace_api::store_provider::get_block ( uint32_t block_height,
const yield_function & yield = {} )

Read the trace for a given block

Parameters
block_height: the height of the data being read
Returns
empty optional if the data cannot be read OTHERWISE optional containing a 2-tuple of the block_trace and a flag indicating irreversibility

Definition at line 74 of file store_provider.cpp.

74 {
75 std::optional<uint64_t> trace_offset;
76 bool irreversible = false;
77 scan_metadata_log_from(block_height, 0, [&block_height, &trace_offset, &irreversible](const metadata_log_entry& e) -> bool {
78 if (std::holds_alternative<block_entry_v0>(e)) {
79 const auto& block = std::get<block_entry_v0>(e);
80 if (block.number == block_height) {
81 trace_offset = block.offset;
82 }
83 } else if (std::holds_alternative<lib_entry_v0>(e)) {
84 auto lib = std::get<lib_entry_v0>(e).lib;
85 if (lib >= block_height) {
86 irreversible = true;
87 return false;
88 }
89 }
90 return true;
91 }, yield);
92 if (!trace_offset) {
93 return get_block_t{};
94 }
95 std::optional<data_log_entry> entry = read_data_log(block_height, *trace_offset);
96 if (!entry) {
97 return get_block_t{};
98 }
99 return std::make_tuple( entry.value(), irreversible );
100 }
uint64_t scan_metadata_log_from(uint32_t block_height, uint64_t offset, Fn &&fn, const yield_function &yield)
std::optional< data_log_entry > read_data_log(uint32_t block_height, uint64_t offset)
thread_local yield_t yield
Definition yield.hpp:52
std::optional< std::tuple< data_log_entry, bool > > get_block_t
Definition common.hpp:49
Here is the call graph for this function:

◆ get_trx_block_number()

get_block_n sysio::trace_api::store_provider::get_trx_block_number ( const chain::transaction_id_type & trx_id,
std::optional< uint32_t > minimum_irreversible_history_blocks,
const yield_function & yield = {} )

Definition at line 102 of file store_provider.cpp.

102 {
103 fc::cfile trx_id_file;
104 int32_t slice_number;
105 if (minimum_irreversible_history_blocks) {
106 slice_number = _slice_directory.slice_number(*minimum_irreversible_history_blocks);
107 } else {
108 slice_number = 0;
109 }
110
111 uint32_t trx_block_num = 0; // number of the block that contains the target trx
112 uint32_t trx_entries = 0; // number of entries that contain the target trx
113 while (true){
114 const bool found = _slice_directory.find_trx_id_slice(slice_number, open_state::read, trx_id_file);
115 if( !found )
116 break; // traversed all slices
117
118 metadata_log_entry entry;
119 auto ds = trx_id_file.create_datastream();
120 const uint64_t end = file_size(trx_id_file.get_file_path());
121 uint64_t offset = trx_id_file.tellp();
122 while (offset < end) {
123 yield();
124 fc::raw::unpack(ds, entry);
125 if (std::holds_alternative<block_trxs_entry>(entry)) {
126 const auto& trxs_entry = std::get<block_trxs_entry>(entry);
127 for (auto i = 0U; i < trxs_entry.ids.size(); ++i) {
128 if (trxs_entry.ids[i] == trx_id) {
129 trx_entries++;
130 trx_block_num = trxs_entry.block_num;
131 }
132 }
133 } else if (std::holds_alternative<lib_entry_v0>(entry)) {
134 auto lib = std::get<lib_entry_v0>(entry).lib;
135 if (trx_entries > 0 && lib >= trx_block_num) {
136 return trx_block_num;
137 }
138 } else {
139 FC_ASSERT( false, "unpacked data should be a block_trxs_entry or a lib_entry_v0" );;
140 }
141 offset = trx_id_file.tellp();
142 }
143 slice_number++;
144 }
145
146 // transaction's block is not irreversible
147 if (trx_entries > 0)
148 return trx_block_num;
149
150 return get_block_n{};
151 }
cfile_datastream create_datastream()
Definition cfile.hpp:249
fc::path get_file_path() const
Definition cfile.hpp:41
size_t tellp() const
Definition cfile.hpp:79
bool find_trx_id_slice(uint32_t slice_number, open_state state, fc::cfile &trx_id_file, bool open_file=true) const
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
static const Segment ds(Segment::ds)
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
uint64_t file_size(const path &p)
std::optional< uint32_t > get_block_n
Definition common.hpp:51
signed int int32_t
Definition stdint.h:123
Definition dtoa.c:306
Here is the call graph for this function:

◆ initialize_new_index_slice_file()

void sysio::trace_api::store_provider::initialize_new_index_slice_file ( fc::cfile & index)
protected

Initialize a new index slice with a valid header

Parameters
index: index file to open and add header to

◆ read_data_log()

std::optional< data_log_entry > sysio::trace_api::store_provider::read_data_log ( uint32_t block_height,
uint64_t offset )
inlineprotected

Read from the data log

Parameters
block_height: the block_height of the data being read
offset: the offset in the datalog to read
Returns
empty optional if the data log does not exist, data otherwise
Exceptions
std::exception: when the data is not the correct type or if the log is corrupt in some way

Definition at line 336 of file store_provider.hpp.

336 {
337 const uint32_t slice_number = _slice_directory.slice_number(block_height);
338
339 fc::cfile trace;
340 if( !_slice_directory.find_trace_slice(slice_number, open_state::read, trace) ) {
341 // attempt to read a compressed trace if one exists
342 std::optional<compressed_file> ctrace = _slice_directory.find_compressed_trace_slice(slice_number);
343 if (ctrace) {
344 ctrace->seek(offset);
345 return extract_store<data_log_entry>(*ctrace);
346 }
347
348 const std::string offset_str = boost::lexical_cast<std::string>(offset);
349 const std::string bh_str = boost::lexical_cast<std::string>(block_height);
350 throw malformed_slice_file("Requested offset: " + offset_str + " to retrieve block number: " + bh_str + " but this trace file is new, so there are no traces present.");
351 }
352 const uint64_t end = file_size(trace.get_file_path());
353 if( offset >= end ) {
354 const std::string offset_str = boost::lexical_cast<std::string>(offset);
355 const std::string bh_str = boost::lexical_cast<std::string>(block_height);
356 const std::string end_str = boost::lexical_cast<std::string>(end);
357 throw malformed_slice_file("Requested offset: " + offset_str + " to retrieve block number: " + bh_str + " but this trace file only goes to offset: " + end_str);
358 }
359 trace.seek(offset);
360 return extract_store<data_log_entry>(trace);
361 }
void seek(long loc)
Definition cfile.hpp:87
bool find_trace_slice(uint32_t slice_number, open_state state, fc::cfile &trace_file, bool open_file=true) const
std::optional< compressed_file > find_compressed_trace_slice(uint32_t slice_number, bool open_file=true) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scan_metadata_log_from()

template<typename Fn >
uint64_t sysio::trace_api::store_provider::scan_metadata_log_from ( uint32_t block_height,
uint64_t offset,
Fn && fn,
const yield_function & yield )
inlineprotected

Read the metadata log font-to-back starting at an offset passing each entry to a provided functor/lambda

Template Parameters
Fn: type of the functor/lambda
Parameters
block_height: height of the requested data
offset: initial offset to read from
fn: the functor/lambda
Returns
the highest offset read during this scan

Definition at line 304 of file store_provider.hpp.

304 {
305 // ignoring offset
306 offset = 0;
307 fc::cfile index;
308 const uint32_t slice_number = _slice_directory.slice_number(block_height);
309 const bool found = _slice_directory.find_index_slice(slice_number, open_state::read, index);
310 if( !found ) {
311 return 0;
312 }
313 const uint64_t end = file_size(index.get_file_path());
314 offset = index.tellp();
315 uint64_t last_read_offset = offset;
316 while (offset < end) {
317 yield();
318 const auto metadata = extract_store<metadata_log_entry>(index);
319 if(! fn(metadata)) {
320 break;
321 }
322 last_read_offset = offset;
323 offset = index.tellp();
324 }
325 return last_read_offset;
326 }
bool find_index_slice(uint32_t slice_number, open_state state, fc::cfile &index_file, bool open_file=true) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_maintenance_thread()

void sysio::trace_api::store_provider::start_maintenance_thread ( log_handler log)
inline

Definition at line 286 of file store_provider.hpp.

286 {
288 }
void start_maintenance_thread(log_handler log)
Here is the call graph for this function:

◆ stop_maintenance_thread()

void sysio::trace_api::store_provider::stop_maintenance_thread ( )
inline

Definition at line 289 of file store_provider.hpp.

Here is the call graph for this function:

◆ validate_existing_index_slice_file()

void sysio::trace_api::store_provider::validate_existing_index_slice_file ( fc::cfile & index,
open_state state )
protected

Ensure an existing index slice has a valid header

Parameters
index: index file to open and read header from
state: indicate if the file is going to be written to (appended) or read

Member Data Documentation

◆ _slice_directory

slice_directory sysio::trace_api::store_provider::_slice_directory
protected

Definition at line 378 of file store_provider.hpp.


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