37 lines
1.1 KiB
C++
37 lines
1.1 KiB
C++
#include "lm/interpolate/bounded_sequence_encoding.hh"
|
|
|
|
#include <algorithm>
|
|
|
|
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
|