xcdat/src/FitVector.cpp

61 lines
1.5 KiB
C++
Raw Normal View History

2017-03-29 06:01:06 +00:00
#include "FitVector.hpp"
namespace xcdat {
2017-07-12 06:48:49 +00:00
FitVector::FitVector(std::istream& is) {
chunks_ = Vector<id_type>(is);
size_= read_value<size_t>(is);
width_ = read_value<id_type>(is);
mask_ = read_value<id_type>(is);
}
FitVector::FitVector(const std::vector<id_type>& values) {
if (values.empty()) {
2017-03-29 06:01:06 +00:00
return;
}
width_ = 0;
2017-07-12 06:48:49 +00:00
auto max_value = *std::max_element(std::begin(values), std::end(values));
2017-03-29 06:01:06 +00:00
do {
++width_;
max_value >>= 1;
} while (max_value);
2017-07-12 06:48:49 +00:00
size_ = values.size();
2017-03-29 06:01:06 +00:00
mask_ = (1U << width_) - 1;
std::vector<id_type> chunks(size_ * width_ / kChunkWidth + 1, 0);
for (id_type i = 0; i < size_; ++i) {
2017-07-12 06:48:49 +00:00
const auto chunk_pos = static_cast<id_type>(i * width_ / kChunkWidth);
const auto offset = static_cast<id_type>(i * width_ % kChunkWidth);
2017-03-29 06:01:06 +00:00
chunks[chunk_pos] &= ~(mask_ << offset);
2017-07-12 06:48:49 +00:00
chunks[chunk_pos] |= (values[i] & mask_) << offset;
2017-03-29 06:01:06 +00:00
if (kChunkWidth < offset + width_) {
chunks[chunk_pos + 1] &= ~(mask_ >> (kChunkWidth - offset));
2017-07-12 06:48:49 +00:00
chunks[chunk_pos + 1] |= (values[i] & mask_) >> (kChunkWidth - offset);
2017-03-29 06:01:06 +00:00
}
}
2017-07-12 06:48:49 +00:00
chunks_ = Vector<id_type>(chunks);
2017-03-29 06:01:06 +00:00
}
size_t FitVector::size_in_bytes() const {
size_t ret = 0;
ret += chunks_.size_in_bytes();
ret += sizeof(size_);
ret += sizeof(width_);
ret += sizeof(mask_);
return ret;
}
void FitVector::write(std::ostream& os) const {
chunks_.write(os);
write_value(size_, os);
write_value(width_, os);
write_value(mask_, os);
}
} //namespace - xcdat