23 BitBucket(simdb::TinyStrings<>* tiny_strings, simdb::argos::EnumInspector* enum_inspector) :
24 tiny_strings_(tiny_strings),
25 enum_inspector_(enum_inspector)
29 virtual void clear() = 0;
30 virtual void writeTo(simdb::argos::EntryPoint* entry_point) = 0;
33 void writeField(
const T& val, uint32_t field_id) {
35 if constexpr (std::is_same_v<T, bool>) {
36 writeField(val ? uint8_t(1) : uint8_t(0), field_id);
41 using value_type =
typename T::value_type;
43 const uint8_t count =
static_cast<uint8_t
>(val.size());
44 writeField_(
static_cast<const void*
>(&count),
sizeof(count), field_id);
45 if constexpr (std::is_integral_v<value_type> && !std::is_same_v<value_type, bool>) {
46 for (
const auto& elem : val) {
47 writeField(elem, field_id);
50 using converted_t = simdb::type_traits::pod_convertible_t<value_type>;
51 static_assert(simdb::type_traits::is_pod_convertible_v<value_type> &&
52 std::is_integral_v<converted_t> && !std::is_same_v<converted_t, bool>,
53 "Argos vector collection only supports integer vectors or integer-like values.");
54 for (
const auto& elem : val) {
55 writeField(
static_cast<converted_t
>(elem), field_id);
61 else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<std::decay_t<T>,
const char*>) {
62 writeField(tiny_strings_->getStringID(val), field_id);
66 else if constexpr (std::is_enum_v<T>) {
67 enum_inspector_->inspect(val);
68 using underlying_t = std::underlying_type_t<T>;
69 const underlying_t enum_int =
static_cast<underlying_t
>(val);
70 writeField(enum_int, field_id);
74 else if constexpr (simdb::type_traits::is_pod_convertible_v<T> && !std::is_enum_v<T> &&
75 (!std::is_trivial_v<T> || !std::is_standard_layout_v<T>)) {
76 using converted_t = simdb::type_traits::pod_convertible_t<T>;
77 static_assert(std::is_trivial_v<converted_t> && std::is_standard_layout_v<converted_t>);
78 auto converted_val =
static_cast<converted_t
>(val);
79 writeField(converted_val, field_id);
84 else if constexpr (std::is_trivial_v<T> && std::is_standard_layout_v<T>) {
85 writeField_(&val,
sizeof(T), field_id);
107 throw simdb::DBException(
"Invalid type! Must be a POD, enum, or string, not ")
108 << simdb::demangle_type<T>();
112 simdb::TinyStrings<>* getTinyStrings()
const {
113 return tiny_strings_;
116 simdb::argos::EnumInspector* getEnumInspector()
const {
117 return enum_inspector_;
121 virtual void writeField_(
const void* data, uint32_t bytes, uint32_t field_id) = 0;
124 simdb::TinyStrings<>* tiny_strings_ =
nullptr;
125 simdb::argos::EnumInspector* enum_inspector_ =
nullptr;
137 using BitBucket::BitBucket;
139 void clear()
override final {
141 buffer_.reserve(bytes_per_pass_);
146 void writeTo(simdb::argos::EntryPoint* entry_point)
override final {
147 entry_point->setScalarValueBytes(std::move(buffer_));
153 std::swap(dest, buffer_);
158 void writeField_(
const void* data, uint32_t bytes, uint32_t)
override final {
159 auto src =
static_cast<const char*
>(data);
160 buffer_.resize(bytes_per_pass_ + bytes);
161 auto dst = &buffer_[bytes_per_pass_];
162 memcpy(dst, src, bytes);
163 bytes_per_pass_ += bytes;
166 std::vector<char> buffer_;
167 size_t bytes_per_pass_ = 0;
169 template <
bool Sparse>
170 friend class IterableCollectorBitBucket;
180 :
BitBucket(tiny_strings, enum_inspector)
181 , capacity_(capacity)
184 all_bin_idxs_.reserve(capacity_);
187 bin_buckets_.emplace_back(std::make_unique<CollectableBitBucket>(tiny_strings, enum_inspector));
191 void clear()
override final {
192 active_bin_idx_.clearValid();
193 all_bin_idxs_.clear();
194 all_bin_idxs_.reserve(capacity_);
197 void setActiveBinIdx(uint32_t bin_idx) {
199 active_bin_idx_ =
static_cast<uint16_t
>(bin_idx);
200 all_bin_idxs_.emplace_back(bin_idx);
203 void writeTo(simdb::argos::EntryPoint* entry_point)
override final {
204 for (
auto bin_idx : all_bin_idxs_) {
205 bin_buckets_.at(bin_idx)->writeTo(all_bin_bytes_[bin_idx]);
208 entry_point->setSparseContainerBinBytes(std::move(all_bin_bytes_));
213 void writeField_(
const void* data, uint32_t bytes, uint32_t field_id)
override final {
214 auto& bin_bucket = bin_buckets_.at(active_bin_idx_.getValue());
216 bin_bucket->writeField_(data, bytes, field_id);
219 std::vector<std::unique_ptr<CollectableBitBucket>> bin_buckets_;
220 std::map<uint16_t, std::vector<char>> all_bin_bytes_;
222 std::vector<uint16_t> all_bin_idxs_;
223 size_t capacity_ = 0;
233 :
BitBucket(tiny_strings, enum_inspector)
234 , capacity_(capacity)
236 all_bin_bytes_.reserve(capacity_);
239 bin_buckets_.emplace_back(std::make_unique<CollectableBitBucket>(tiny_strings, enum_inspector));
243 void clear()
override final {
245 all_bin_bytes_.reserve(capacity_);
248 void setActiveBinIdx(uint32_t bin_idx) {
254 void writeTo(simdb::argos::EntryPoint* entry_point)
override final {
255 all_bin_bytes_.resize(container_size_);
256 for (
size_t i = 0; i < container_size_; ++i) {
257 auto & bin_bucket = bin_buckets_.at(i);
258 auto & bin_buffer = all_bin_bytes_.at(i);
259 bin_bucket->writeTo(bin_buffer);
262 entry_point->setContigContainerBinBytes(std::move(all_bin_bytes_));
267 void writeField_(
const void* data, uint32_t bytes, uint32_t field_id)
override final {
271 auto& bin_bucket = bin_buckets_.at(container_size_ - 1);
272 bin_bucket->writeField_(data, bytes, field_id);
275 std::vector<std::unique_ptr<CollectableBitBucket>> bin_buckets_;
276 std::vector<std::vector<char>> all_bin_bytes_;
277 uint16_t container_size_ = 0;
278 size_t capacity_ = 0;