21#include <alien/utils/ArrayUtils.h>
22#include <alien/utils/Precomp.h>
23#include <arccore/base/ArccoreGlobal.h>
25#define VMAP_USE_REALLOC
34template <
typename IndexT,
typename DataT>
36intrusive_vmap_insert(IndexT new_index, Integer& hint_pos, Integer& size,
37 Integer capacity, IndexT* indexes, DataT* data)
41 if (hint_pos < size and indexes[hint_pos] == new_index) {
42 return &data[hint_pos];
44 else if (size < capacity) {
45 for (Integer i = size; i > hint_pos; --i) {
46 data[i] = data[i - 1];
47 indexes[i] = indexes[i - 1];
49 indexes[hint_pos] = new_index;
50 data[hint_pos] = DataT();
52 return &data[hint_pos];
65template <
typename IndexT,
typename DataT>
74 iterator(VMap& vmap, Integer index)
79 DataT& value() {
return m_vmap.m_data[m_index]; }
81 const IndexT& key()
const {
return m_vmap.m_indexes[m_index]; }
83 iterator& operator++()
89 bool operator==(
const iterator& i)
const {
return (m_index == i.m_index); }
91 bool operator!=(
const iterator& i)
const {
return (m_index != i.m_index); }
98 friend class const_iterator;
104 const_iterator(
const VMap& vmap, Integer index)
109 explicit const_iterator(
const iterator& itr)
111 , m_index(itr.m_index)
114 const DataT& value()
const {
return m_vmap.m_data[m_index]; }
116 const IndexT& key()
const {
return m_vmap.m_indexes[m_index]; }
118 const_iterator& operator++()
124 bool operator==(
const const_iterator& i)
const {
return (m_index == i.m_index); }
126 bool operator!=(
const const_iterator& i)
const {
return (m_index != i.m_index); }
134 explicit VMap(Integer first_capacity = 4);
138 VMap(
const VMap& vmap);
140 VMap& operator=(
const VMap& vmap);
143 DataT& operator[](IndexT index);
149 std::pair<iterator, bool> insert(IndexT index);
153 const_iterator end()
const {
return const_iterator(*
this, m_size); }
155 iterator begin() {
return iterator(*
this, 0); }
159 [[nodiscard]] Integer size()
const {
return m_size; }
162 Integer m_size, m_capacity;
168 static Integer new_capacity(Integer capacity);
173template <
typename IndexT,
typename DataT>
174VMap<IndexT, DataT>::VMap(
const Integer first_capacity)
176, m_capacity(first_capacity)
178 m_memory_pool = malloc(m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
179 m_data = (DataT*)m_memory_pool;
180 m_indexes = (IndexT*)(m_data + m_capacity);
185template <
typename IndexT,
typename DataT>
186VMap<IndexT, DataT>::VMap(
const VMap& vmap)
188, m_capacity(vmap.m_capacity)
190 m_memory_pool = malloc(m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
191 m_data = (DataT*)m_memory_pool;
192 m_indexes = (IndexT*)(m_data + m_capacity);
194 m_memory_pool, vmap.m_memory_pool, m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
199template <
typename IndexT,
typename DataT>
201VMap<IndexT, DataT>::operator=(
const VMap& vmap)
203 m_size = vmap.m_size;
204 m_capacity = vmap.m_capacity;
206 m_memory_pool = malloc(m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
208 m_memory_pool, vmap.m_memory_pool, m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
209 m_data = (DataT*)m_memory_pool;
210 m_indexes = (IndexT*)(m_data + m_capacity);
216template <
typename IndexT,
typename DataT>
217VMap<IndexT, DataT>::~VMap()
224template <
typename IndexT,
typename DataT>
226VMap<IndexT, DataT>::operator[](
const IndexT index)
228 return insert(index).first.value();
233template <
typename IndexT,
typename DataT>
234typename VMap<IndexT, DataT>::iterator
235VMap<IndexT, DataT>::find(
const IndexT index)
247template <
typename IndexT,
typename DataT>
248typename VMap<IndexT, DataT>::const_iterator
249VMap<IndexT, DataT>::find(
const IndexT index)
const
261template <
typename IndexT,
typename DataT>
262std::pair<typename VMap<IndexT, DataT>::iterator,
bool>
263VMap<IndexT, DataT>::insert(
const IndexT index)
265 Integer old_size = m_size;
267 Integer hint_pos = 0;
269 intrusive_vmap_insert(index, hint_pos, m_size, m_capacity, m_indexes, m_data);
271 Integer old_capacity = m_capacity;
272 m_capacity = new_capacity(m_capacity);
275#ifdef VMAP_USE_REALLOC
276 m_memory_pool = realloc(m_memory_pool, m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
277 m_data = (DataT*)m_memory_pool;
278 m_indexes = (IndexT*)(m_data + m_capacity);
280 auto* old_data = (DataT*)m_memory_pool;
281 auto* old_indexes = (IndexT*)(old_data + old_capacity);
283 for (Integer i = old_capacity; i > hint_pos; --i)
284 m_indexes[i] = old_indexes[i - 1];
285 m_indexes[hint_pos] = index;
286 for (Integer i = hint_pos; --i >= 0;)
287 m_indexes[i] = old_indexes[i];
288 for (Integer i = old_capacity; i > hint_pos; --i)
289 m_data[i] = old_data[i - 1];
293 void* old_memory_pool = m_memory_pool;
294 DataT* old_data = (DataT*)old_memory_pool;
295 IndexT* old_indexes = (IndexT*)(old_data + old_capacity);
297 m_memory_pool = malloc(m_capacity * (
sizeof(IndexT) +
sizeof(DataT)));
300 m_data = (DataT*)m_memory_pool;
301 m_indexes = (IndexT*)(m_data + m_capacity);
303 for (Integer i = old_capacity; i > hint_pos; --i)
304 m_indexes[i] = old_indexes[i - 1];
305 m_indexes[hint_pos] = index;
306 for (Integer i = hint_pos; --i >= 0;)
307 m_indexes[i] = old_indexes[i];
308 for (Integer i = old_capacity; i > hint_pos; --i)
309 m_data[i] = old_data[i - 1];
310 for (Integer i = 0; i < hint_pos; ++i)
311 m_data[i] = old_data[i];
313 free(old_memory_pool);
317 m_data[hint_pos] = DataT();
320 return std::pair<iterator, bool>(
iterator(*
this, hint_pos), m_size != old_size);
325template <
typename IndexT,
typename DataT>
327VMap<IndexT, DataT>::new_capacity(
const Integer capacity)
331 else if (capacity < 4096)
332 return 2 * capacity + 12;
334 return capacity + 4096;
Integer dichotomicScan(const T &x, ConstArrayView< T > v)
Integer dichotomicPositionScan(const T &x, ConstArrayView< T > v)
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --