0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / TCollection / TCollection_IndexedDataMap.gxx
CommitLineData
b311480e 1// Created on: 1993-01-08
2// Created by: Remi LEQUETTE
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <Standard_DomainError.hxx>
18#include <Standard_MultiplyDefined.hxx>
19#include <Standard_NoSuchObject.hxx>
20#include <Standard_OutOfRange.hxx>
21#include <TCollection_BasicMapIterator.hxx>
22
23//=======================================================================
24//function : TCollection_IndexedDataMap
25//purpose :
26//=======================================================================
27
28TCollection_IndexedDataMap::TCollection_IndexedDataMap
29 (const Standard_Integer NbBuckets):
30 TCollection_BasicMap(NbBuckets,Standard_False)
31{
32}
33
34//=======================================================================
35//function : TCollection_IndexedDataMap
36//purpose :
37//=======================================================================
38
39TCollection_IndexedDataMap::TCollection_IndexedDataMap
40 (const TCollection_IndexedDataMap& Other) :
41 TCollection_BasicMap(Other.NbBuckets(),Standard_False)
42{
43 if (Other.Extent() != 0)
9775fa61 44 throw Standard_DomainError("TCollection:Copy of non empty IndexedDataMap");
7fd59977 45}
46
47//=======================================================================
48//function : Assign
49//purpose :
50//=======================================================================
51
52TCollection_IndexedDataMap& TCollection_IndexedDataMap::Assign
53 (const TCollection_IndexedDataMap& Other)
54{
55 // very simple implementation
56 // not optimal (recompute the hashcode values)
57
58 if (this == &Other) return *this;
59 Clear();
60// ReSize(Other.NbBuckets());
61 if (!Other.IsEmpty()) {
62 ReSize(Other.Extent());
63 for (Standard_Integer i = 1; i <= Other.Extent(); i++) {
64 Add(Other.FindKey(i),Other(i));
65 }
66 }
67 return *this;
68}
69
70
71
72//=======================================================================
73//function : ReSize
74//purpose :
75//=======================================================================
76
77void TCollection_IndexedDataMap::ReSize(const Standard_Integer N)
78{
79 Standard_Integer newBuck;
80 Standard_Address newData1=NULL, newData2=NULL;
81 if (BeginResize(N,newBuck,newData1,newData2)) {
82 if (myData1) {
83 TCollection_IndexedDataMapNode** newdata1 = (TCollection_IndexedDataMapNode**)newData1;
84 TCollection_IndexedDataMapNode** newdata2 = (TCollection_IndexedDataMapNode**)newData2;
85 TCollection_IndexedDataMapNode** olddata1 = (TCollection_IndexedDataMapNode**) myData1;
86 TCollection_IndexedDataMapNode *p, *q;
87 Standard_Integer i,k1,k2;
88 for (i = 0; i <= NbBuckets(); i++) {
89 if (olddata1[i]) {
90 p = olddata1[i];
91 while (p) {
92 k1 = Hasher::HashCode(p->Key1(),newBuck);
93 k2 = ::HashCode(p->Key2(),newBuck);
94 q = (TCollection_IndexedDataMapNode*)p->Next();
95 p->Next() = newdata1[k1];
96 p->Next2() = newdata2[k2];
97 newdata1[k1] = p;
98 newdata2[k2] = p;
99 p = q;
100 }
101 }
102 }
103 }
104 EndResize(N,newBuck,newData1,newData2);
105 }
106}
107
108//=======================================================================
109//function : Clear
110//purpose :
111//=======================================================================
112
113void TCollection_IndexedDataMap::Clear()
114{
115 if (!IsEmpty()) {
116 Standard_Integer i;
117 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**) myData1;
118 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**) myData2;
119 TCollection_IndexedDataMapNode *p,*q;
120 for (i = 0; i <= NbBuckets(); i++) {
121 p = data1[i];
122 while (p) {
123 q = (TCollection_IndexedDataMapNode*) p->Next();
124 delete p;
125 p = q;
126 }
127 data1[i] = data2[i] = NULL;
128 }
129 }
130 TCollection_BasicMap::Destroy();
131}
132
133//=======================================================================
134//function : Add
135//purpose :
136//=======================================================================
137
138Standard_Integer TCollection_IndexedDataMap::Add(const TheKey& K1, const TheItem& I)
139{
140 if (Resizable()) ReSize(Extent());
141 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
142 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
143 TCollection_IndexedDataMapNode* p;
144 p = data1[k1];
145 while (p) {
146 if (Hasher::IsEqual(p->Key1(),K1))
147 return p->Key2();
148 p = (TCollection_IndexedDataMapNode*) p->Next();
149 }
150 Increment();
151 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
152 Standard_Integer k2 = ::HashCode(Extent(),NbBuckets());
153 p = new TCollection_IndexedDataMapNode(K1,Extent(),I,data1[k1],data2[k2]);
154 data1[k1] = p;
155 data2[k2] = p;
156 return Extent();
157}
158
159
160//=======================================================================
161//function : Substitute
162//purpose :
163//=======================================================================
164
165void TCollection_IndexedDataMap::Substitute(const Standard_Integer I,
985aed12 166 const TheKey& K1,
167 const TheItem& T)
7fd59977 168{
985aed12 169 Standard_OutOfRange_Raise_if(I < 1 || I > Extent(), "IndexedDataMap::Substitute : "
170 "Index is out of range");
7fd59977 171 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
172 TCollection_IndexedDataMapNode* p;
173
174 // check if K1 is not already in the map
175 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
176 p = data1[k1];
177 while (p) {
985aed12 178 if (Hasher::IsEqual(p->Key1(),K1)) {
179 if (p->Key2() != I)
9775fa61 180 throw Standard_DomainError("IndexedDataMap::Substitute : "
181 "Attempt to substitute existing key");
985aed12 182 p->Key1() = K1;
183 p->Value() = T;
184 return;
185 }
7fd59977 186 p = (TCollection_IndexedDataMapNode*) p->Next();
187 }
188
189 // Find the node for the index I
190 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
191 Standard_Integer k2 = ::HashCode(I,NbBuckets());
192 p = data2[k2];
193 while (p) {
194 if (p->Key2() == I)
195 break;
196 p = (TCollection_IndexedDataMapNode*) p->Next2();
197 }
198
199 // remove the old key
200 Standard_Integer k = Hasher::HashCode(p->Key1(),NbBuckets());
201 TCollection_IndexedDataMapNode* q = data1[k];
202 if (q == p) data1[k] = (TCollection_IndexedDataMapNode*) p->Next();
203 else {
204 while(q->Next() != p) q = (TCollection_IndexedDataMapNode*) q->Next();
205 q->Next() = p->Next();
206 }
207
208 // update the node
209 p->Key1() = K1;
210 p->Value() = T;
211 p->Next() = data1[k1];
212 data1[k1] = p;
213}
214
215//=======================================================================
216//function : RemoveLast
217//purpose :
218//=======================================================================
219
220void TCollection_IndexedDataMap::RemoveLast()
221{
222 Standard_OutOfRange_Raise_if(Extent() == 0,
223 "IndexedMap::RemoveLast");
224 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
225 TCollection_IndexedDataMapNode* p;
226 TCollection_IndexedDataMapNode* q;
227
228 // Find the node for the last index and remove it
229 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
230 Standard_Integer k2 = ::HashCode(Extent(),NbBuckets());
231 p = data2[k2];
232 q = NULL;
233 while (p) {
234 if (p->Key2() == Extent())
235 break;
236 q = p;
237 p = (TCollection_IndexedDataMapNode*) p->Next2();
238 }
239 if (q == NULL)
240 data2[k2] = (TCollection_IndexedDataMapNode*)p->Next2();
241 else
242 q->Next2() = p->Next2();
243
244 // remove the key
245 Standard_Integer k = Hasher::HashCode(p->Key1(),NbBuckets());
246 q = data1[k];
247 if (q == p) data1[k] = (TCollection_IndexedDataMapNode*) p->Next();
248 else {
249 while(q->Next() != p) q = (TCollection_IndexedDataMapNode*) q->Next();
250 q->Next() = p->Next();
251 }
252
253 Decrement();
254 delete p;
255}
256
7fd59977 257
258//=======================================================================
259//function : FindKey
260//purpose :
261//=======================================================================
262
263const TheKey& TCollection_IndexedDataMap::FindKey(const Standard_Integer K2) const
264{
265 Standard_OutOfRange_Raise_if(K2 < 1 || K2 > Extent(), "IndexedDataMap");
266 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
267 Standard_Integer k2 = ::HashCode(K2,NbBuckets());
268 TCollection_IndexedDataMapNode *p2;
269 p2 = data2[k2];
270 while (p2) {
271 if (p2->Key2() == K2) return p2->Key1();
272 p2 = (TCollection_IndexedDataMapNode*)p2->Next2();
273 }
9775fa61 274 throw Standard_OutOfRange("IndexedDataMap : missing index !!!");
7fd59977 275 return p2->Key1();
276}
277
278//=======================================================================
279//function : FindFromIndex
280//purpose :
281//=======================================================================
282
283const TheItem& TCollection_IndexedDataMap::FindFromIndex
284 (const Standard_Integer K2) const
285{
286 Standard_OutOfRange_Raise_if(K2 < 1 || K2 > Extent(), "IndexedDataMap");
287 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
288 Standard_Integer k2 = ::HashCode(K2,NbBuckets());
289 TCollection_IndexedDataMapNode *p2;
290 p2 = data2[k2];
291 while (p2) {
292 if (p2->Key2() == K2) return p2->Value();
293 p2 = (TCollection_IndexedDataMapNode*)p2->Next2();
294 }
9775fa61 295 throw Standard_OutOfRange("IndexedDataMap : missing index !!!");
7fd59977 296 return p2->Value();
297}
298
299//=======================================================================
300//function : ChangeFromIndex
301//purpose :
302//=======================================================================
303
304TheItem& TCollection_IndexedDataMap::ChangeFromIndex(const Standard_Integer K2)
305{
306 Standard_OutOfRange_Raise_if(K2 < 1 || K2 > Extent(), "IndexedDataMap");
307 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
308 Standard_Integer k2 = ::HashCode(K2,NbBuckets());
309 TCollection_IndexedDataMapNode *p2;
310 p2 = data2[k2];
311 while (p2) {
312 if (p2->Key2() == K2) return p2->Value();
313 p2 = (TCollection_IndexedDataMapNode*)p2->Next2();
314 }
9775fa61 315 throw Standard_OutOfRange("IndexedDataMap : missing index !!!");
7fd59977 316 return p2->Value();
317}
318
319//=======================================================================
320//function : FindIndex
321//purpose :
322//=======================================================================
323
324Standard_Integer TCollection_IndexedDataMap::FindIndex(const TheKey& K1) const
325{
326 if (IsEmpty()) return 0;
327 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
328 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
329 TCollection_IndexedDataMapNode *p1;
330 p1 = data1[k1];
331 while (p1) {
332 if (Hasher::IsEqual(p1->Key1(),K1)) return p1->Key2();
333 p1 = (TCollection_IndexedDataMapNode*)p1->Next();
334 }
335 return 0;
336}
cf8e963a 337//=======================================================================
338//function : Contains
339//purpose :
340//=======================================================================
341Standard_Boolean TCollection_IndexedDataMap::Contains(const TheKey& K1) const
342{
343 if (IsEmpty()) return Standard_False;
344 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
345 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
346 TCollection_IndexedDataMapNode *p1;
347 p1 = data1[k1];
348 while (p1) {
349 if (Hasher::IsEqual(p1->Key1(),K1)) return Standard_True;
350 p1 = (TCollection_IndexedDataMapNode*) p1->Next();
351 }
352 return Standard_False;
353}
7fd59977 354//=======================================================================
355//function : FindFromKey
356//purpose :
357//=======================================================================
7fd59977 358const TheItem& TCollection_IndexedDataMap::FindFromKey(const TheKey& K1) const
359{
360 Standard_OutOfRange_Raise_if(IsEmpty(),"TCollection_IndexedDataMap::FindFromKey");
361 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
362 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
363 TCollection_IndexedDataMapNode *p1;
364 p1 = data1[k1];
365 while (p1) {
366 if (Hasher::IsEqual(p1->Key1(),K1)) return p1->Value();
367 p1 = (TCollection_IndexedDataMapNode*) p1->Next();
368 }
9775fa61 369 throw Standard_OutOfRange("TCollection_IndexedDataMap::FindFromKey");
7fd59977 370 return p1->Value();
371}
7fd59977 372//=======================================================================
373//function : ChangeFromKey
374//purpose :
375//=======================================================================
7fd59977 376TheItem& TCollection_IndexedDataMap::ChangeFromKey(const TheKey& K1)
377{
378 Standard_OutOfRange_Raise_if(IsEmpty(),"TCollection_IndexedDataMap::ChangeFromKey");
379 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
380 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
381 TCollection_IndexedDataMapNode *p1;
382 p1 = data1[k1];
383 while (p1) {
384 if (Hasher::IsEqual(p1->Key1(),K1)) return p1->Value();
385 p1 = (TCollection_IndexedDataMapNode*)p1->Next();
386 }
9775fa61 387 throw Standard_OutOfRange("TCollection_IndexedDataMap::ChangeFromKey");
7fd59977 388 return p1->Value();
389}
cf8e963a 390//modified by NIZNHY-PKV Tue Jul 05 08:37:03 2011f
391//=======================================================================
392//function : FindFromKey1
393//purpose :
394//=======================================================================
395Standard_Address TCollection_IndexedDataMap::FindFromKey1(const TheKey& K1) const
396{
397 TCollection_IndexedDataMap *pMap=(TCollection_IndexedDataMap *)this;
398 return pMap->ChangeFromKey1(K1);
399}
400//=======================================================================
401//function : ChangeFromKey1
402//purpose :
403//=======================================================================
404Standard_Address TCollection_IndexedDataMap::ChangeFromKey1(const TheKey& K1)
405{
406 if (IsEmpty()) {
407 return NULL;
408 }
409 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
410 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
411 TCollection_IndexedDataMapNode *p1;
412 p1 = data1[k1];
413 while (p1) {
414 if (Hasher::IsEqual(p1->Key1(),K1)) {
415 return (Standard_Address)&p1->Value();
416 }
417 p1 = (TCollection_IndexedDataMapNode*) p1->Next();
418 }
419 return NULL;
420}