Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::chain::detail::reverse_iterator Class Reference

Public Member Functions

 reverse_iterator ()
 
uint32_t open (const fc::path &block_file_name)
 
uint64_t previous ()
 
uint32_t version () const
 
uint32_t first_block_num () const
 

Static Public Attributes

static uint32_t _buf_len = 1U << 24
 

Detailed Description

Definition at line 146 of file block_log.cpp.

Constructor & Destructor Documentation

◆ reverse_iterator()

sysio::chain::detail::reverse_iterator::reverse_iterator ( )

Definition at line 1009 of file block_log.cpp.

1010 : _file(nullptr, &fclose)
1011 , _buffer_ptr(std::make_unique<char[]>(_buf_len)) {
1012 }

Member Function Documentation

◆ first_block_num()

uint32_t sysio::chain::detail::reverse_iterator::first_block_num ( ) const
inline

Definition at line 153 of file block_log.cpp.

153{ return _first_block_num; }
Here is the caller graph for this function:

◆ open()

uint32_t sysio::chain::detail::reverse_iterator::open ( const fc::path & block_file_name)

Definition at line 1016 of file block_log.cpp.

1016 {
1017 _block_file_name = block_file_name.generic_string();
1018 _file.reset( FC_FOPEN(_block_file_name.c_str(), "r"));
1019 SYS_ASSERT( _file, block_log_exception, "Could not open Block log file at '${blocks_log}'", ("blocks_log", _block_file_name) );
1020 _end_of_buffer_position = _unset_position;
1021
1022 //read block log to see if version 1 or 2 and get first blocknum (implicit 1 if version 1)
1023 _version = 0;
1024 auto size = fread((char*)&_version, sizeof(_version), 1, _file.get());
1025 SYS_ASSERT( size == 1, block_log_exception, "Block log file at '${blocks_log}' could not be read.", ("file", _block_file_name) );
1026 const bool is_prune_log = is_pruned_log_and_mask_version(_version);
1027 SYS_ASSERT( block_log::is_supported_version(_version), block_log_unsupported_version,
1028 "block log version ${v} is not supported", ("v", _version));
1029 if (_version == 1) {
1030 _first_block_num = 1;
1031 }
1032 else {
1033 size = fread((char*)&_first_block_num, sizeof(_first_block_num), 1, _file.get());
1034 SYS_ASSERT( size == 1, block_log_exception, "Block log file at '${blocks_log}' not formatted consistently with version ${v}.", ("file", _block_file_name)("v", _version) );
1035 }
1036
1037 auto status = fseek(_file.get(), 0, SEEK_END);
1038 SYS_ASSERT( status == 0, block_log_exception, "Could not open Block log file at '${blocks_log}'. Returned status: ${status}", ("blocks_log", _block_file_name)("status", status) );
1039
1040 auto eof_position_in_file = ftell(_file.get());
1041 SYS_ASSERT( eof_position_in_file > 0, block_log_exception, "Block log file at '${blocks_log}' could not be read.", ("blocks_log", _block_file_name) );
1042
1043 if(is_prune_log) {
1044 fseek(_file.get(), -sizeof(uint32_t), SEEK_CUR);
1045 uint32_t prune_count;
1046 size = fread((char*)&prune_count, sizeof(prune_count), 1, _file.get());
1047 SYS_ASSERT( size == 1, block_log_exception, "Block log file at '${blocks_log}' not formatted consistently with pruned version ${v}.", ("file", _block_file_name)("v", _version) );
1048 _prune_block_limit = prune_count;
1049 eof_position_in_file -= sizeof(prune_count);
1050 }
1051
1052 _current_position_in_file = eof_position_in_file - _position_size;
1053
1054 update_buffer();
1055
1056 _blocks_found = 0;
1057 char* buf = _buffer_ptr.get();
1058 const uint32_t index_of_pos = _current_position_in_file - _start_of_buffer_position;
1059 const uint64_t block_pos = *reinterpret_cast<uint64_t*>(buf + index_of_pos);
1060
1061 if (block_pos == block_log::npos) {
1062 return 0;
1063 }
1064
1065 uint32_t bnum = 0;
1066 if (block_pos >= _start_of_buffer_position) {
1067 const uint32_t index_of_block = block_pos - _start_of_buffer_position;
1068 bnum = *reinterpret_cast<uint32_t*>(buf + index_of_block + trim_data::blknum_offset); //block number of previous block (is big endian)
1069 }
1070 else {
1071 const auto blknum_offset_pos = block_pos + trim_data::blknum_offset;
1072 auto status = fseek(_file.get(), blknum_offset_pos, SEEK_SET);
1073 SYS_ASSERT( status == 0, block_log_exception, "Could not seek in '${blocks_log}' to position: ${pos}. Returned status: ${status}", ("blocks_log", _block_file_name)("pos", blknum_offset_pos)("status", status) );
1074 auto size = fread((void*)&bnum, sizeof(bnum), 1, _file.get());
1075 SYS_ASSERT( size == 1, block_log_exception, "Could not read in '${blocks_log}' at position: ${pos}", ("blocks_log", _block_file_name)("pos", blknum_offset_pos) );
1076 }
1077 _last_block_num = fc::endian_reverse_u32(bnum) + 1; //convert from big endian to little endian and add 1
1078 _blocks_expected = _last_block_num - _first_block_num + 1;
1079 return _blocks_expected;
1080 }
#define FC_FOPEN(p, m)
Definition block_log.cpp:16
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
std::string generic_string() const
static const uint64_t npos
Definition block_log.hpp:73
static bool is_supported_version(uint32_t version)
uint32_t endian_reverse_u32(uint32_t x)
Definition bitutil.hpp:19
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
static constexpr int blknum_offset
uint8_t buf[2048]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ previous()

uint64_t sysio::chain::detail::reverse_iterator::previous ( )

Definition at line 1082 of file block_log.cpp.

1082 {
1083 SYS_ASSERT( _current_position_in_file != block_log::npos,
1084 block_log_exception,
1085 "Block log file at '${blocks_log}' first block already returned by former call to previous(), it is no longer valid to call this function.", ("blocks_log", _block_file_name) );
1086
1087 if ((_version == 1 && _blocks_found == _blocks_expected) || (_prune_block_limit && _blocks_found == *_prune_block_limit)) {
1088 _current_position_in_file = block_log::npos;
1089 return _current_position_in_file;
1090 }
1091
1092 if (_start_of_buffer_position > _current_position_in_file) {
1093 update_buffer();
1094 }
1095
1096 char* buf = _buffer_ptr.get();
1097 auto offset = _current_position_in_file - _start_of_buffer_position;
1098 uint64_t block_location_in_file = *reinterpret_cast<uint64_t*>(buf + offset);
1099
1100 ++_blocks_found;
1101 if (block_location_in_file == block_log::npos) {
1102 _current_position_in_file = block_location_in_file;
1103 SYS_ASSERT( _blocks_found != _blocks_expected,
1104 block_log_exception,
1105 "Block log file at '${blocks_log}' formatting indicated last block: ${last_block_num}, first block: ${first_block_num}, but found ${num} blocks",
1106 ("blocks_log", _block_file_name)("last_block_num", _last_block_num)("first_block_num", _first_block_num)("num", _blocks_found) );
1107 }
1108 else {
1109 const uint64_t previous_position_in_file = _current_position_in_file;
1110 _current_position_in_file = block_location_in_file - _position_size;
1111 SYS_ASSERT( _current_position_in_file < previous_position_in_file,
1112 block_log_exception,
1113 "Block log file at '${blocks_log}' formatting is incorrect, indicates position later location in file: ${pos}, which was retrieved at: ${orig_pos}.",
1114 ("blocks_log", _block_file_name)("pos", _current_position_in_file)("orig_pos", previous_position_in_file) );
1115 }
1116
1117 return block_location_in_file;
1118 }
Here is the caller graph for this function:

◆ version()

uint32_t sysio::chain::detail::reverse_iterator::version ( ) const
inline

Definition at line 152 of file block_log.cpp.

152{ return _version; }
Here is the caller graph for this function:

Member Data Documentation

◆ _buf_len

uint32_t sysio::chain::detail::reverse_iterator::_buf_len = 1U << 24
static

Definition at line 154 of file block_log.cpp.


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