in sampling/include/var_opt_sketch_impl.hpp [400:459]
void var_opt_sketch<T, A>::serialize(std::ostream& os, const SerDe& sd) const {
const bool empty = (h_ == 0) && (r_ == 0);
const uint8_t preLongs = (empty ? PREAMBLE_LONGS_EMPTY
: (r_ == 0 ? PREAMBLE_LONGS_WARMUP : PREAMBLE_LONGS_FULL));
const uint8_t first_byte = (preLongs & 0x3F) | ((static_cast<uint8_t>(rf_)) << 6);
uint8_t flags = (marks_ != nullptr ? GADGET_FLAG_MASK : 0);
if (empty) {
flags |= EMPTY_FLAG_MASK;
}
// first prelong
const uint8_t ser_ver(SER_VER);
const uint8_t family(FAMILY_ID);
write(os, first_byte);
write(os, ser_ver);
write(os, family);
write(os, flags);
write(os, k_);
if (!empty) {
// second and third prelongs
write(os, n_);
write(os, h_);
write(os, r_);
// fourth prelong, if needed
if (r_ > 0) {
write(os, total_wt_r_);
}
// write the first h_ weights
write(os, weights_, h_ * sizeof(double));
// write the first h_ marks as packed bytes iff we have a gadget
if (marks_ != nullptr) {
uint8_t val = 0;
for (uint32_t i = 0; i < h_; ++i) {
if (marks_[i]) {
val |= 0x1 << (i & 0x7);
}
if ((i & 0x7) == 0x7) {
write(os, val);
val = 0;
}
}
// write out any remaining values
if ((h_ & 0x7) > 0) {
write(os, val);
}
}
// write the sample items, skipping the gap. Either h_ or r_ may be 0
sd.serialize(os, data_, h_);
sd.serialize(os, &data_[h_ + 1], r_);
}
}