namespace lm { namespace interpolate { | |
BoundedSequenceEncoding::BoundedSequenceEncoding(const unsigned char *bound_begin, const unsigned char *bound_end) | |
: entries_(bound_end - bound_begin) { | |
std::size_t full = 0; | |
Entry entry; | |
entry.shift = 0; | |
for (const unsigned char *i = bound_begin; i != bound_end; ++i) { | |
uint8_t length; | |
if (*i <= 1) { | |
length = 0; | |
} else { | |
length = sizeof(unsigned int) * 8 - __builtin_clz((unsigned int)*i); | |
} | |
entry.mask = (1ULL << length) - 1ULL; | |
if (entry.shift + length > 64) { | |
entry.shift = 0; | |
entry.next = true; | |
++full; | |
} else { | |
entry.next = false; | |
} | |
entries_.push_back(entry); | |
entry.shift += length; | |
} | |
byte_length_ = full * sizeof(uint64_t) + (entry.shift + 7) / 8; | |
first_copy_ = std::min<std::size_t>(byte_length_, sizeof(uint64_t)); | |
// Size of last uint64_t. Zero if empty, otherwise [1,8] depending on mod. | |
overhang_ = byte_length_ == 0 ? 0 : ((byte_length_ - 1) % 8 + 1); | |
} | |
}} // namespaces | |