@@ -33,16 +33,61 @@ namespace table {
3333struct header
3434 : public hash_map<schema::header>
3535{
36+ using head = schema::header::link;
3637 using hash_map<schema::header>::hashmap;
38+ static constexpr auto offset = head::bits;
39+ static_assert (offset < to_bits(head::size));
40+
41+ static constexpr size_t skip_to_height =
42+ context::flag_t ::size;
43+
44+ static constexpr size_t skip_to_mtp =
45+ skip_to_height +
46+ context::height_t ::size;
47+
48+ static constexpr size_t skip_to_parent =
49+ skip_to_mtp +
50+ sizeof (uint32_t );
51+
52+ static constexpr size_t skip_to_version =
53+ skip_to_parent +
54+ link::size;
55+
56+ static constexpr size_t skip_to_timestamp =
57+ skip_to_version +
58+ sizeof (uint32_t );
59+
60+ static constexpr size_t skip_to_bits =
61+ skip_to_timestamp +
62+ sizeof (uint32_t );
63+
64+ static constexpr head::integer merge (bool milestone,
65+ head::integer parent_fk) NOEXCEPT
66+ {
67+ using namespace system ;
68+ BC_ASSERT_MSG (!get_right (parent_fk, offset), " overflow" );
69+ return set_right (parent_fk, offset, milestone);
70+ }
71+
72+ static constexpr bool is_milestone (link::integer merged) NOEXCEPT
73+ {
74+ return system::get_right (merged, offset);
75+ }
76+
77+ static constexpr link::integer to_parent (link::integer merged) NOEXCEPT
78+ {
79+ return system::set_right (merged, offset, false );
80+ }
3781
3882 struct record
3983 : public schema::header
4084 {
4185 inline bool from_data (reader& source) NOEXCEPT
4286 {
4387 context::from_data (source, ctx);
44- milestone = to_bool (source.read_byte ());
45- parent_fk = source.read_little_endian <link::integer, link::size>();
88+ const auto merged = source.read_little_endian <link::integer, link::size>();
89+ milestone = is_milestone (merged);
90+ parent_fk = to_parent (merged);
4691 version = source.read_little_endian <uint32_t >();
4792 timestamp = source.read_little_endian <uint32_t >();
4893 bits = source.read_little_endian <uint32_t >();
@@ -55,8 +100,7 @@ struct header
55100 inline bool to_data (finalizer& sink) const NOEXCEPT
56101 {
57102 context::to_data (sink, ctx);
58- sink.write_byte (to_int<uint8_t >(milestone));
59- sink.write_little_endian <link::integer, link::size>(parent_fk);
103+ sink.write_little_endian <link::integer, link::size>(merge (milestone, parent_fk));
60104 sink.write_little_endian <uint32_t >(version);
61105 sink.write_little_endian <uint32_t >(timestamp);
62106 sink.write_little_endian <uint32_t >(bits);
@@ -96,8 +140,7 @@ struct header
96140 inline bool to_data (finalizer& sink) const NOEXCEPT
97141 {
98142 context::to_data (sink, ctx);
99- sink.write_byte (to_int<uint8_t >(milestone));
100- sink.write_little_endian <link::integer, link::size>(parent_fk);
143+ sink.write_little_endian <link::integer, link::size>(merge (milestone, parent_fk));
101144 sink.write_little_endian <uint32_t >(header.version ());
102145 sink.write_little_endian <uint32_t >(header.timestamp ());
103146 sink.write_little_endian <uint32_t >(header.bits ());
@@ -144,109 +187,117 @@ struct header
144187 key key{};
145188 };
146189
147- struct get_version
190+ struct record_context
148191 : public schema::header
149192 {
150193 inline bool from_data (reader& source) NOEXCEPT
151194 {
152- source.skip_bytes (context::size + schema::bit + link::size);
153- version = source.read_little_endian <uint32_t >();
195+ context::from_data (source, ctx);
154196 return source;
155197 }
156198
157- uint32_t version {};
199+ context ctx {};
158200 };
159201
160- struct get_timestamp
202+ struct get_flags
161203 : public schema::header
162204 {
205+ using flag_t = context::flag_t ;
163206 inline bool from_data (reader& source) NOEXCEPT
164207 {
165- source.skip_bytes (context::size + schema::bit + link::size +
166- sizeof (uint32_t ));
167- timestamp = source.read_little_endian <uint32_t >();
208+ flags = source.read_little_endian <flag_t ::integer, flag_t ::size>();
168209 return source;
169210 }
170211
171- uint32_t timestamp {};
212+ flag_t ::integer flags {};
172213 };
173214
174- struct get_bits
215+ struct get_height
175216 : public schema::header
176217 {
218+ using height_t = context::height_t ;
177219 inline bool from_data (reader& source) NOEXCEPT
178220 {
179- source.skip_bytes (context::size + schema::bit + link::size +
180- sizeof (uint32_t ) + sizeof (uint32_t ));
181- bits = source.read_little_endian <uint32_t >();
221+ source.skip_bytes (skip_to_height);
222+ height = source.read_little_endian <height_t ::integer, height_t ::size>();
182223 return source;
183224 }
184225
185- uint32_t bits{};
226+ height_t ::integer height{};
227+ };
228+
229+ struct get_mtp
230+ : public schema::header
231+ {
232+ inline bool from_data (reader& source) NOEXCEPT
233+ {
234+ source.skip_bytes (skip_to_mtp);
235+ mtp = source.read_little_endian <uint32_t >();
236+ return source;
237+ }
238+
239+ context::mtp_t mtp{};
186240 };
187241
188242 struct get_parent_fk
189243 : public schema::header
190244 {
191245 inline bool from_data (reader& source) NOEXCEPT
192246 {
193- source.skip_bytes (context::size + schema::bit );
194- parent_fk = source.read_little_endian <link::integer, link::size>();
247+ source.skip_bytes (skip_to_parent );
248+ parent_fk = to_parent ( source.read_little_endian <link::integer, link::size>() );
195249 return source;
196250 }
197251
198252 link::integer parent_fk{};
199253 };
200254
201- struct get_flags
255+ struct get_version
202256 : public schema::header
203257 {
204- using flag_t = context::flag_t ;
205-
206258 inline bool from_data (reader& source) NOEXCEPT
207259 {
208- flags = source.read_little_endian <flag_t ::integer, flag_t ::size>();
260+ source.skip_bytes (skip_to_version);
261+ version = source.read_little_endian <uint32_t >();
209262 return source;
210263 }
211264
212- flag_t ::integer flags {};
265+ uint32_t version {};
213266 };
214267
215- struct get_height
268+ struct get_timestamp
216269 : public schema::header
217270 {
218- using height_t = context::height_t ;
219-
220271 inline bool from_data (reader& source) NOEXCEPT
221272 {
222- source.skip_bytes (context:: flag_t ::size );
223- height = source.read_little_endian <height_t ::integer, height_t ::size >();
273+ source.skip_bytes (skip_to_timestamp );
274+ timestamp = source.read_little_endian <uint32_t >();
224275 return source;
225276 }
226277
227- height_t ::integer height {};
278+ uint32_t timestamp {};
228279 };
229280
230- struct get_mtp
281+ struct get_bits
231282 : public schema::header
232283 {
233284 inline bool from_data (reader& source) NOEXCEPT
234285 {
235- source.skip_bytes (context:: flag_t ::size + context:: height_t ::size );
236- mtp = source.read_little_endian <uint32_t >();
286+ source.skip_bytes (skip_to_bits );
287+ bits = source.read_little_endian <uint32_t >();
237288 return source;
238289 }
239290
240- context:: mtp_t mtp {};
291+ uint32_t bits {};
241292 };
242293
243294 struct get_milestone
244295 : public schema::header
245296 {
246297 inline bool from_data (reader& source) NOEXCEPT
247298 {
248- source.skip_bytes (context::size );
249- milestone = to_bool (source.read_byte ());
299+ source.skip_bytes (skip_to_parent );
300+ milestone = is_milestone (source.read_little_endian <link::integer, link::size> ());
250301 return source;
251302 }
252303
@@ -261,7 +312,7 @@ struct header
261312 source.rewind_bytes (sk);
262313 key = source.read_hash ();
263314 context::from_data (source, ctx);
264- source.skip_bytes (schema::bit + link::size + sizeof ( uint32_t ) );
315+ source.skip_bytes (skip_to_timestamp - skip_to_parent );
265316 timestamp = source.read_little_endian <uint32_t >();
266317 return source;
267318 }
@@ -270,18 +321,6 @@ struct header
270321 context ctx{};
271322 uint32_t timestamp{};
272323 };
273-
274- struct record_context
275- : public schema::header
276- {
277- inline bool from_data (reader& source) NOEXCEPT
278- {
279- context::from_data (source, ctx);
280- return source;
281- }
282-
283- context ctx{};
284- };
285324};
286325
287326} // namespace table
0 commit comments