1 #ifndef gamgee__short_value_optimized_storage__guard
2 #define gamgee__short_value_optimized_storage__guard
23 template<
class ELEMENT_TYPE>
28 m_max_value_length { 0 },
29 m_short_value_upper_bound { short_value_upper_bound },
31 m_contiguous_storage(
capacity * short_value_upper_bound)
33 if ( short_value_upper_bound == 0 ) {
34 throw std::invalid_argument{
"short value upper bound must be > 0"};
37 for (
auto i = 0u; i < m_values.size(); ++i ) {
38 m_values[i].first =
nullptr;
39 m_values[i].second = 0u;
62 uint32_t
capacity()
const {
return m_values.size(); }
74 return m_values[index].second;
80 bool is_set(
const uint32_t index)
const {
81 return index <
capacity() && m_values[index].first !=
nullptr;
87 std::pair<ELEMENT_TYPE*,uint32_t>
get(
const uint32_t index)
const {
89 return m_values[index];
95 void set(
const uint32_t index,
const std::vector<ELEMENT_TYPE>& values) {
96 if ( values.empty() )
return;
97 set(index, &(values[0]), values.size());
103 void set(
const uint32_t index,
const ELEMENT_TYPE* values,
const uint32_t
num_values) {
105 if ( num_values == 0 || values ==
nullptr )
return;
111 if ( m_values[index].first ==
nullptr ) { ++m_num_values; }
114 prepare_memory(index, num_values);
117 memcpy(m_values[index].first, values, num_values *
sizeof(ELEMENT_TYPE));
120 if ( num_values > m_max_value_length) m_max_value_length =
num_values;
129 if ( !
is_set(index) )
return;
131 const auto previous_length = m_values[index].second;
132 release_memory_if_necessary(index);
136 if ( previous_length == m_max_value_length ) {
137 recalculate_max_value_length();
145 for (
auto i = 0u; i < m_values.size(); ++i ) {
146 release_memory_if_necessary(i);
149 m_max_value_length = 0;
153 uint32_t m_num_values;
154 uint32_t m_max_value_length;
155 uint32_t m_short_value_upper_bound;
156 std::vector<std::pair<ELEMENT_TYPE*,uint32_t>> m_values;
157 std::vector<ELEMENT_TYPE> m_contiguous_storage;
163 void prepare_memory(
const uint32_t index,
const uint32_t
num_values) {
165 release_memory_if_necessary(index);
168 if ( num_values <= m_short_value_upper_bound ) {
169 m_values[index].first = &(m_contiguous_storage[index * m_short_value_upper_bound]);
175 m_values[index].first =
new ELEMENT_TYPE[
num_values];
186 void release_memory_if_necessary(
const uint32_t index) {
188 if ( m_values[index].first !=
nullptr &&
189 m_values[index].first != &(m_contiguous_storage[index * m_short_value_upper_bound]) ) {
195 delete[] m_values[index].first;
198 m_values[index].first =
nullptr;
199 m_values[index].second = 0;
206 void recalculate_max_value_length() {
207 m_max_value_length = 0u;
209 for (
auto& value : m_values ) {
210 if ( value.first !=
nullptr && value.second > m_max_value_length ) {
211 m_max_value_length = value.second;
void clear(const uint32_t index)
Clear the value at a specific index.
Definition: short_value_optimized_storage.h:128
void check_max_boundary(const uint32_t index, const uint32_t size, const std::string &prefix_msg)
checks that an index is greater than or equal to size
Definition: utils.h:63
uint32_t capacity() const
Returns the maximum number of values the container can hold.
Definition: short_value_optimized_storage.h:62
bool is_set(const uint32_t index) const
Determines whether there is a value at the specified position.
Definition: short_value_optimized_storage.h:80
uint32_t value_length(const uint32_t index) const
Returns the length of the value at the specified position.
Definition: short_value_optimized_storage.h:72
void clear()
Reset storage to a pristine state with no values.
Definition: short_value_optimized_storage.h:144
ShortValueOptimizedStorage & operator=(ShortValueOptimizedStorage &&other)=default
uint32_t max_value_length() const
Returns the length of the longest value in the container.
Definition: short_value_optimized_storage.h:67
ShortValueOptimizedStorage(const uint32_t capacity, const uint32_t short_value_upper_bound)
Definition: short_value_optimized_storage.h:26
~ShortValueOptimizedStorage()
Definition: short_value_optimized_storage.h:43
Definition: exceptions.h:9
void set(const uint32_t index, const std::vector< ELEMENT_TYPE > &values)
Set the value at the specified index by vector.
Definition: short_value_optimized_storage.h:95
Definition: short_value_optimized_storage.h:24
uint32_t num_values() const
Returns the number of values in the container.
Definition: short_value_optimized_storage.h:57
void set(const uint32_t index, const ELEMENT_TYPE *values, const uint32_t num_values)
Set the value at the specified index by pointer.
Definition: short_value_optimized_storage.h:103