1 // Created on: 1993-01-08
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
23 //=======================================================================
24 //function : TCollection_IndexedDataMap
26 //=======================================================================
28 TCollection_IndexedDataMap::TCollection_IndexedDataMap
29 (const Standard_Integer NbBuckets):
30 TCollection_BasicMap(NbBuckets,Standard_False)
34 //=======================================================================
35 //function : TCollection_IndexedDataMap
37 //=======================================================================
39 TCollection_IndexedDataMap::TCollection_IndexedDataMap
40 (const TCollection_IndexedDataMap& Other) :
41 TCollection_BasicMap(Other.NbBuckets(),Standard_False)
43 if (Other.Extent() != 0)
44 Standard_DomainError::Raise("TCollection:Copy of non empty IndexedDataMap");
47 //=======================================================================
50 //=======================================================================
52 TCollection_IndexedDataMap& TCollection_IndexedDataMap::Assign
53 (const TCollection_IndexedDataMap& Other)
55 // very simple implementation
56 // not optimal (recompute the hashcode values)
58 if (this == &Other) return *this;
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));
72 //=======================================================================
75 //=======================================================================
77 void TCollection_IndexedDataMap::ReSize(const Standard_Integer N)
79 Standard_Integer newBuck;
80 Standard_Address newData1=NULL, newData2=NULL;
81 if (BeginResize(N,newBuck,newData1,newData2)) {
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++) {
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];
104 EndResize(N,newBuck,newData1,newData2);
108 //=======================================================================
111 //=======================================================================
113 void TCollection_IndexedDataMap::Clear()
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++) {
123 q = (TCollection_IndexedDataMapNode*) p->Next();
127 data1[i] = data2[i] = NULL;
130 TCollection_BasicMap::Destroy();
133 //=======================================================================
136 //=======================================================================
138 Standard_Integer TCollection_IndexedDataMap::Add(const TheKey& K1, const TheItem& I)
140 if (Resizable()) ReSize(Extent());
141 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
142 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
143 TCollection_IndexedDataMapNode* p;
146 if (Hasher::IsEqual(p->Key1(),K1))
148 p = (TCollection_IndexedDataMapNode*) p->Next();
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]);
160 //=======================================================================
161 //function : Substitute
163 //=======================================================================
165 void TCollection_IndexedDataMap::Substitute(const Standard_Integer I,
169 Standard_OutOfRange_Raise_if(I < 1 || I > Extent(),
170 "IndexedMap::Substitute");
171 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
172 TCollection_IndexedDataMapNode* p;
174 // check if K1 is not already in the map
175 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
178 if (Hasher::IsEqual(p->Key1(),K1))
179 Standard_DomainError::Raise("IndexedMap::Substitute");
180 p = (TCollection_IndexedDataMapNode*) p->Next();
183 // Find the node for the index I
184 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
185 Standard_Integer k2 = ::HashCode(I,NbBuckets());
190 p = (TCollection_IndexedDataMapNode*) p->Next2();
193 // remove the old key
194 Standard_Integer k = Hasher::HashCode(p->Key1(),NbBuckets());
195 TCollection_IndexedDataMapNode* q = data1[k];
196 if (q == p) data1[k] = (TCollection_IndexedDataMapNode*) p->Next();
198 while(q->Next() != p) q = (TCollection_IndexedDataMapNode*) q->Next();
199 q->Next() = p->Next();
205 p->Next() = data1[k1];
209 //=======================================================================
210 //function : RemoveLast
212 //=======================================================================
214 void TCollection_IndexedDataMap::RemoveLast()
216 Standard_OutOfRange_Raise_if(Extent() == 0,
217 "IndexedMap::RemoveLast");
218 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
219 TCollection_IndexedDataMapNode* p;
220 TCollection_IndexedDataMapNode* q;
222 // Find the node for the last index and remove it
223 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
224 Standard_Integer k2 = ::HashCode(Extent(),NbBuckets());
228 if (p->Key2() == Extent())
231 p = (TCollection_IndexedDataMapNode*) p->Next2();
234 data2[k2] = (TCollection_IndexedDataMapNode*)p->Next2();
236 q->Next2() = p->Next2();
239 Standard_Integer k = Hasher::HashCode(p->Key1(),NbBuckets());
241 if (q == p) data1[k] = (TCollection_IndexedDataMapNode*) p->Next();
243 while(q->Next() != p) q = (TCollection_IndexedDataMapNode*) q->Next();
244 q->Next() = p->Next();
252 //=======================================================================
255 //=======================================================================
257 const TheKey& TCollection_IndexedDataMap::FindKey(const Standard_Integer K2) const
259 Standard_OutOfRange_Raise_if(K2 < 1 || K2 > Extent(), "IndexedDataMap");
260 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
261 Standard_Integer k2 = ::HashCode(K2,NbBuckets());
262 TCollection_IndexedDataMapNode *p2;
265 if (p2->Key2() == K2) return p2->Key1();
266 p2 = (TCollection_IndexedDataMapNode*)p2->Next2();
268 Standard_OutOfRange::Raise("IndexedDataMap : missing index !!!");
272 //=======================================================================
273 //function : FindFromIndex
275 //=======================================================================
277 const TheItem& TCollection_IndexedDataMap::FindFromIndex
278 (const Standard_Integer K2) const
280 Standard_OutOfRange_Raise_if(K2 < 1 || K2 > Extent(), "IndexedDataMap");
281 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
282 Standard_Integer k2 = ::HashCode(K2,NbBuckets());
283 TCollection_IndexedDataMapNode *p2;
286 if (p2->Key2() == K2) return p2->Value();
287 p2 = (TCollection_IndexedDataMapNode*)p2->Next2();
289 Standard_OutOfRange::Raise("IndexedDataMap : missing index !!!");
293 //=======================================================================
294 //function : ChangeFromIndex
296 //=======================================================================
298 TheItem& TCollection_IndexedDataMap::ChangeFromIndex(const Standard_Integer K2)
300 Standard_OutOfRange_Raise_if(K2 < 1 || K2 > Extent(), "IndexedDataMap");
301 TCollection_IndexedDataMapNode** data2 = (TCollection_IndexedDataMapNode**)myData2;
302 Standard_Integer k2 = ::HashCode(K2,NbBuckets());
303 TCollection_IndexedDataMapNode *p2;
306 if (p2->Key2() == K2) return p2->Value();
307 p2 = (TCollection_IndexedDataMapNode*)p2->Next2();
309 Standard_OutOfRange::Raise("IndexedDataMap : missing index !!!");
313 //=======================================================================
314 //function : FindIndex
316 //=======================================================================
318 Standard_Integer TCollection_IndexedDataMap::FindIndex(const TheKey& K1) const
320 if (IsEmpty()) return 0;
321 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
322 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
323 TCollection_IndexedDataMapNode *p1;
326 if (Hasher::IsEqual(p1->Key1(),K1)) return p1->Key2();
327 p1 = (TCollection_IndexedDataMapNode*)p1->Next();
331 //=======================================================================
332 //function : Contains
334 //=======================================================================
335 Standard_Boolean TCollection_IndexedDataMap::Contains(const TheKey& K1) const
337 if (IsEmpty()) return Standard_False;
338 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
339 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
340 TCollection_IndexedDataMapNode *p1;
343 if (Hasher::IsEqual(p1->Key1(),K1)) return Standard_True;
344 p1 = (TCollection_IndexedDataMapNode*) p1->Next();
346 return Standard_False;
348 //=======================================================================
349 //function : FindFromKey
351 //=======================================================================
352 const TheItem& TCollection_IndexedDataMap::FindFromKey(const TheKey& K1) const
354 Standard_OutOfRange_Raise_if(IsEmpty(),"TCollection_IndexedDataMap::FindFromKey");
355 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
356 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
357 TCollection_IndexedDataMapNode *p1;
360 if (Hasher::IsEqual(p1->Key1(),K1)) return p1->Value();
361 p1 = (TCollection_IndexedDataMapNode*) p1->Next();
363 Standard_OutOfRange::Raise("TCollection_IndexedDataMap::FindFromKey");
366 //=======================================================================
367 //function : ChangeFromKey
369 //=======================================================================
370 TheItem& TCollection_IndexedDataMap::ChangeFromKey(const TheKey& K1)
372 Standard_OutOfRange_Raise_if(IsEmpty(),"TCollection_IndexedDataMap::ChangeFromKey");
373 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
374 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
375 TCollection_IndexedDataMapNode *p1;
378 if (Hasher::IsEqual(p1->Key1(),K1)) return p1->Value();
379 p1 = (TCollection_IndexedDataMapNode*)p1->Next();
381 Standard_OutOfRange::Raise("TCollection_IndexedDataMap::ChangeFromKey");
384 //modified by NIZNHY-PKV Tue Jul 05 08:37:03 2011f
385 //=======================================================================
386 //function : FindFromKey1
388 //=======================================================================
389 Standard_Address TCollection_IndexedDataMap::FindFromKey1(const TheKey& K1) const
391 TCollection_IndexedDataMap *pMap=(TCollection_IndexedDataMap *)this;
392 return pMap->ChangeFromKey1(K1);
394 //=======================================================================
395 //function : ChangeFromKey1
397 //=======================================================================
398 Standard_Address TCollection_IndexedDataMap::ChangeFromKey1(const TheKey& K1)
403 TCollection_IndexedDataMapNode** data1 = (TCollection_IndexedDataMapNode**)myData1;
404 Standard_Integer k1 = Hasher::HashCode(K1,NbBuckets());
405 TCollection_IndexedDataMapNode *p1;
408 if (Hasher::IsEqual(p1->Key1(),K1)) {
409 return (Standard_Address)&p1->Value();
411 p1 = (TCollection_IndexedDataMapNode*) p1->Next();