aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/datastore/array_store_dynamic_type_mapper.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'vespalib/src/vespa/vespalib/datastore/array_store_dynamic_type_mapper.hpp')
-rw-r--r--vespalib/src/vespa/vespalib/datastore/array_store_dynamic_type_mapper.hpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/vespalib/src/vespa/vespalib/datastore/array_store_dynamic_type_mapper.hpp b/vespalib/src/vespa/vespalib/datastore/array_store_dynamic_type_mapper.hpp
new file mode 100644
index 00000000000..f529ecccb46
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/datastore/array_store_dynamic_type_mapper.hpp
@@ -0,0 +1,70 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "array_store_dynamic_type_mapper.h"
+#include "dynamic_array_buffer_type.h"
+#include "aligner.h"
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <optional>
+
+namespace vespalib::datastore {
+
+template <typename ElemT>
+ArrayStoreDynamicTypeMapper<ElemT>::ArrayStoreDynamicTypeMapper(uint32_t max_buffer_type_id, double grow_factor)
+ : ArrayStoreTypeMapper(),
+ _max_static_array_buffer_type_id(0)
+{
+ setup_array_sizes(max_buffer_type_id, grow_factor);
+}
+
+template <typename ElemT>
+void
+ArrayStoreDynamicTypeMapper<ElemT>::setup_array_sizes(uint32_t max_buffer_type_id, double grow_factor)
+{
+ _array_sizes.clear();
+ _array_sizes.reserve(max_buffer_type_id + 1);
+ _array_sizes.emplace_back(0); // type id 0 is fallback for large arrays
+ size_t array_size = 1u;
+ size_t entry_size = sizeof(ElemT);
+ bool dynamic_arrays = false;
+ for (uint32_t type_id = 1; type_id <= max_buffer_type_id; ++type_id) {
+ if (type_id > 1) {
+ array_size = std::max(array_size + 1, static_cast<size_t>(std::floor(array_size * grow_factor)));
+ if (array_size > _array_sizes.back() + 1 || dynamic_arrays) {
+ if (!dynamic_arrays) {
+ _max_static_array_buffer_type_id = type_id - 1;
+ dynamic_arrays = true;
+ }
+ entry_size = DynamicBufferType::calc_entry_size(array_size);
+ array_size = DynamicBufferType::calc_array_size(entry_size);
+ } else {
+ entry_size = array_size * sizeof(ElemT);
+ }
+ }
+ if (entry_size > std::numeric_limits<uint32_t>::max()) {
+ break;
+ }
+ _array_sizes.emplace_back(array_size);
+ }
+ if (!dynamic_arrays) {
+ _max_static_array_buffer_type_id = _array_sizes.size() - 1;
+ }
+}
+
+template <typename ElemT>
+ArrayStoreDynamicTypeMapper<ElemT>::~ArrayStoreDynamicTypeMapper() = default;
+
+template <typename ElemT>
+size_t
+ArrayStoreDynamicTypeMapper<ElemT>::get_entry_size(uint32_t type_id) const
+{
+ auto array_size = get_array_size(type_id);
+ if (type_id <= _max_static_array_buffer_type_id) {
+ return array_size * sizeof(ElemT);
+ } else {
+ return DynamicBufferType::calc_entry_size(array_size);
+ }
+}
+
+}