The Sparta Modeling Framework
Loading...
Searching...
No Matches
VectorStorage.hpp
1// <VectorStorage> -*- C++ -*-
2
3#pragma once
4
5#include "sparta/functional/ArchData.hpp"
7
8namespace sparta::serialization::checkpoint::storage
9{
10
15{
16 class Segment{
18 std::vector<char> data_;
19 uint32_t bytes_;
20 public:
21
25 Segment(const Segment&) = default;
26
30 Segment(Segment&& rhp) :
31 idx_(rhp.idx_),
32 data_(std::move(rhp.data_)),
33 bytes_(rhp.bytes_)
34 {
36 rhp.bytes_ = 0;
37 }
38
42 Segment() :
44 bytes_(0)
45 {;}
46
50 Segment& operator=(const Segment& rhp) = delete;
51
55 Segment(ArchData::line_idx_type idx, const char* data, size_t bytes) :
56 idx_(idx), bytes_(bytes)
57 {
59 "Attempted to create segment of " << bytes << " bytes with invalid line index");
60 data_.resize(bytes);
61 ::memcpy(data_.data(), data, bytes);
62 }
63
64 template <typename Archive>
65 void serialize(Archive& ar, const unsigned int /*version*/) {
66 ar & idx_;
67 ar & data_;
68 ar & bytes_;
69 }
70
71 ArchData::line_idx_type getLineIdx() const {
72 return idx_;
73 }
74
75 uint32_t getSize() const {
76 return sizeof(decltype(*this)) + bytes_;
77 }
78
79 void copyTo(char* buf, uint32_t size) const {
80 sparta_assert(size == bytes_, \
81 "Attempted to restore checkpoint data for a line where the "
82 "data was " << bytes_ << " bytes but the loader requested "
83 << size << " bytes. The sizes must match up or something is "
84 "wrong");
85 memcpy(buf, data_.data(), bytes_);
86 }
87
88 void dump(std::ostream& o) const {
90 std::cout << "\nEnd of ArchData";
91 return;
92 }
93
94 std::cout << "\nLine: " << std::dec << idx_ << " (" << bytes_ << ") bytes";
95 for(uint32_t off = 0; off < bytes_;){
96 char chr = data_[off];
97 if(off % 32 == 0){
98 o << std::endl << std::setw(7) << std::hex << off;
99 }
100 if(chr == 0){
101 o << ' ' << "..";
102 }else{
103 o << ' ' << std::setfill('0') << std::setw(2) << std::hex << (0xff & (uint16_t)chr);
104 }
105 off++;
106 }
107 }
108 };
109
113 std::vector<Segment> data_;
114
119
123 uint32_t next_restore_idx_ = 0;
124
129 decltype(data_)::const_iterator cur_restore_itr_;
130
131public:
132 VectorStorage() {
133 }
134
136 }
137
138 VectorStorage(const VectorStorage&) = default;
139
140 template <typename Archive>
141 void serialize(Archive& ar, const unsigned int /*version*/) {
142 ar & data_;
143 }
144
145 void dump(std::ostream& o) const {
146 for(auto const &seg : data_){
147 seg.dump(o);
148 }
149 }
150
151 uint32_t getSize() const {
152 uint32_t bytes = sizeof(decltype(*this));
153 for(Segment const & seg : data_){
154 bytes += seg.getSize();
155 }
156 return bytes;
157 }
158
159 void prepareForLoad() {
160 next_restore_idx_ = 0;
161 cur_restore_itr_ = data_.begin();
162 }
163
164 void beginLine(ArchData::line_idx_type idx) {
166 "Cannot begin line with INVALID_LINE_IDX index");
167 next_idx_ = idx;
168 }
169
170 void writeLineBytes(const char* data, size_t size) {
171 sparta_assert(data_.size() == 0 || data_.back().getLineIdx() != next_idx_,
172 "Cannot store the same line idx twice in a checkpoint. Line "
173 << next_idx_ << " detected twice in a row");
175 "Cannot write line bytes with INVALID_LINE_IDX index");
176 data_.emplace_back(next_idx_, data, size);
177 }
178
182 void endArchData() {
183 data_.emplace_back();
184 }
185
190 bool good() const {
191 return next_restore_idx_ <= data_.size(); // Not past end of stream
192 }
193
199 if(next_restore_idx_ == data_.size()){
200 next_restore_idx_++; // Increment to detect errors
201 return ArchData::INVALID_LINE_IDX; // Done with restore
202 }else if(next_restore_idx_ > data_.size()){ // Past the end
203 throw SpartaException("Failed to restore a checkpoint because ")
204 << "caller tried to keep getting next line even after "
205 "reaching the end of the restore data";
206 }
207 if(next_restore_idx_ != 0){
208 cur_restore_itr_++;
209 }
210 next_restore_idx_++;
211
212 const auto next_line_idx = cur_restore_itr_->getLineIdx(); // May be invalid to indicate end of ArchData
213 return next_line_idx;
214 };
215
219 void copyLineBytes(char* buf, uint32_t size) {
220 sparta_assert(cur_restore_itr_ != data_.end(),
221 "Attempted to copy line bytes from an invalid line iterator");
222 sparta_assert(cur_restore_itr_->getLineIdx() != ArchData::INVALID_LINE_IDX,
223 "About to return line from checkpoint data segment with INVALID_LINE_IDX index");
224 cur_restore_itr_->copyTo(buf, size);
225 }
226
227};
228
229} // namespace sparta::serialization::checkpoint::storage
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
static const line_idx_type INVALID_LINE_IDX
Invalid line index.
Definition ArchData.hpp:112
offset_type line_idx_type
Represents offsets into this ArchData.
Definition ArchData.hpp:59
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Vector of buffers storage implementation.
ArchData::line_idx_type getNextRestoreLine()
Restore next line. Return ArchData::INVALID_LINE_IDX on end of data.
void copyLineBytes(char *buf, uint32_t size)
Read bytes for the current line.
bool good() const
Is the reading state of this storage good? (i.e. haven't tried to read past the end of the data)
void endArchData()
Signals end of this checkpoint's data for one ArchData.