Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
GroupIndexTable.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* GroupIndexTable.cc (C) 2000-2024 */
9/* */
10/* Table de hachage entre un item et sa position dans la table. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/StringBuilder.h"
15#include "arcane/utils/FatalErrorException.h"
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/MemoryUtils.h"
18
19#include "arcane/core/ItemGroupImpl.h"
20#include "arcane/core/ItemGroup.h"
21#include "arcane/core/GroupIndexTable.h"
22
23// TODO: Utiliser un même conteneur pour les 3 span 'm_key_buffer',
24// 'm_next_buffer' et 'm_buckets'
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35GroupIndexTable::
36GroupIndexTable(ItemGroupImpl* group_impl)
37: HashTableBase(0, false)
38, m_group_impl(group_impl)
39, m_key_buffer(MemoryUtils::getDefaultDataAllocator())
40, m_next_buffer(MemoryUtils::getDefaultDataAllocator())
41, m_buckets(MemoryUtils::getDefaultDataAllocator())
42{
43 ARCANE_ASSERT((m_group_impl), ("ItemGroupImpl pointer null"));
44#ifdef ARCANE_ASSERT
45 m_disable_check_integrity = platform::getEnvironmentVariable("ARCANE_ENABLE_GROUPINDEXTABLE_CHECKINTEGRITY").null();
46#endif
47 _updateSpan();
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53void GroupIndexTable::
54_updateSpan()
55{
56 m_view.m_key_buffer_span = m_key_buffer;
57 m_view.m_next_buffer_span = m_next_buffer;
58 m_view.m_buckets_span = m_buckets;
59 m_view.m_nb_bucket = m_nb_bucket;
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65void GroupIndexTable::
66update()
67{
68 ItemGroup group(m_group_impl); // will update group if necessary
69
70 const Integer group_size = group.size();
71 m_nb_bucket = this->nearestPrimeNumber(2 * group_size);
72 m_buckets.resize(m_nb_bucket);
73 m_buckets.fill(-1);
74 m_key_buffer.resize(group_size);
75 m_next_buffer.resize(group_size);
76 _updateSpan();
77
78 ENUMERATE_ITEM (item, group) {
79 const Integer index = item.index();
80 const KeyTypeConstRef key = item->localId();
81 const Integer bucket = _hash(key);
82 ARCANE_ASSERT((_lookupBucket(bucket, key) < 0), ("Already assigned key"));
83 m_key_buffer[index] = key;
84 m_next_buffer[index] = m_buckets[bucket];
85 m_buckets[bucket] = index;
86 }
87
88 ARCANE_ASSERT((_checkIntegrity()), ("GroupIndexTable integrity failed"));
89}
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94void GroupIndexTable::
95compact(const Int32ConstArrayView* infos)
96{
97 ARCANE_UNUSED(infos);
98 // Avec cette version, on suppose que l'ordre relatif des ids n'a pas changé
99 // La taille du groupe n'a pas changé mais on réordonne les données
100 ARCANE_ASSERT((m_group_impl->size() == m_key_buffer.size()), ("Inconsistent sizes"));
101
102#ifdef NDEBUG
103 update();
104#else /* NDEBUG */
105 // identique à update() mais peut faire quelque contrôle si infos!=NULL
106 m_buckets.fill(-1);
107 ItemGroup group(m_group_impl);
108 _updateSpan();
109 ENUMERATE_ITEM (iitem, group) {
110 const KeyTypeConstRef key = iitem.localId();
111 const Integer i = iitem.index();
112 const KeyTypeConstRef old_key = m_key_buffer[iitem.index()];
113 const Integer bucket = _hash(key);
114 ARCANE_ASSERT((_lookupBucket(bucket, key) < 0), ("Already assigned key"));
115 ARCANE_ASSERT((infos == NULL || (*infos)[old_key] == key), ("Inconsistent reorder translation %d vs %d vs %d", (*infos)[old_key], key, old_key));
116 m_key_buffer[i] = key;
117 m_next_buffer[i] = m_buckets[bucket];
118 m_buckets[bucket] = i;
119 }
120 ARCANE_ASSERT((_checkIntegrity()), ("GroupIndexTable integrity failed"));
121#endif /* NDEBUG */
122
123 _updateSpan();
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
129bool GroupIndexTable::
130_hasKey(KeyTypeConstRef id) const
131{
132 const Integer hf = _hash(id);
133 for (Integer i = m_buckets[hf]; i >= 0; i = m_next_buffer[i]) {
134 if (m_key_buffer[i] == id)
135 return true;
136 }
137 return false;
138}
139
140/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142
143bool GroupIndexTable::
144_initialized() const
145{
146 return !m_buckets.empty();
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
152bool GroupIndexTable::
153_checkIntegrity(bool full) const
154{
155 bool integrity = true;
156 if (m_group_impl->size() != m_key_buffer.size()) {
157 StringBuilder b;
158 b += "GroupIndexTable BAD DATA size : group size=";
159 b += m_group_impl->size();
160 b += " vs data size=";
161 b += m_key_buffer.size();
162 throw FatalErrorException(b.toString());
163 integrity = false;
164 }
165#ifdef ARCANE_ASSERT
166 if (!full && m_disable_check_integrity)
167 return integrity;
168#endif
169 ItemGroup group(m_group_impl);
170 ENUMERATE_ITEM (item, group) {
171 const Integer hd = item.index();
172 if (m_key_buffer[hd] != item.localId() || !_hasKey(item.localId())) {
173 StringBuilder b;
174 b += "GroupIndexTable BAD DATA at ";
175 b += item.index();
176 b += " : lid=";
177 b += item.localId();
178 b += m_key_buffer[hd];
179 b += " chk:";
180 b += _hasKey(item.localId());
181 throw FatalErrorException(b.toString());
182 integrity = false;
183 }
184 }
185 return integrity;
186}
187
188/*---------------------------------------------------------------------------*/
189/*---------------------------------------------------------------------------*/
190
191} // namespace Arcane
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.