b311480e |
1 | // Created on: 1993-01-08 |
2 | // Created by: Remi LEQUETTE |
3 | // Copyright (c) 1993-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
7fd59977 |
20 | |
21 | #include <Standard_DomainError.hxx> |
22 | #include <Standard_MultiplyDefined.hxx> |
23 | #include <Standard_NoSuchObject.hxx> |
24 | |
25 | |
26 | //======================================================================= |
27 | //function : TCollection_DoubleMap |
28 | //purpose : |
29 | //======================================================================= |
30 | |
31 | TCollection_DoubleMap::TCollection_DoubleMap(const Standard_Integer NbBuckets): |
32 | TCollection_BasicMap(NbBuckets,Standard_False) |
33 | { |
34 | } |
35 | |
36 | //======================================================================= |
37 | //function : TCollection_DoubleMap |
38 | //purpose : |
39 | //======================================================================= |
40 | |
41 | TCollection_DoubleMap::TCollection_DoubleMap |
42 | (const TCollection_DoubleMap& Other) : |
43 | TCollection_BasicMap(Other.NbBuckets(),Standard_False) |
44 | { |
45 | if (Other.Extent() != 0) |
46 | Standard_DomainError::Raise("TCollection:Copy of DoubleMap"); |
47 | } |
48 | |
49 | //======================================================================= |
50 | //function : Assign |
51 | //purpose : |
52 | //======================================================================= |
53 | |
54 | TCollection_DoubleMap& TCollection_DoubleMap::Assign |
55 | (const TCollection_DoubleMap& Other) |
56 | { |
57 | if (this == &Other) return *this; |
58 | Clear(); |
59 | // ReSize(Other.NbBuckets()); |
60 | if (!Other.IsEmpty()) { |
61 | ReSize(Other.Extent()); |
62 | for (TCollection_DoubleMapIterator It(Other); It.More(); It.Next()) { |
63 | Bind(It.Key1(),It.Key2()); |
64 | } |
65 | } |
66 | return *this; |
67 | } |
68 | |
69 | |
70 | //======================================================================= |
71 | //function : ReSize |
72 | //purpose : |
73 | //======================================================================= |
74 | |
75 | void TCollection_DoubleMap::ReSize(const Standard_Integer N) |
76 | { |
77 | Standard_Integer newBuck; |
78 | Standard_Address newData1=NULL, newData2=NULL; |
79 | if (BeginResize(N,newBuck,newData1,newData2)) { |
80 | if (myData1) { |
81 | TCollection_DoubleMapNode** newdata1 = (TCollection_DoubleMapNode**) newData1; |
82 | TCollection_DoubleMapNode** newdata2 = (TCollection_DoubleMapNode**) newData2; |
83 | TCollection_DoubleMapNode** olddata1 = (TCollection_DoubleMapNode**) myData1; |
84 | TCollection_DoubleMapNode *p, *q; |
85 | Standard_Integer i,k1,k2; |
86 | for (i = 0; i <= NbBuckets(); i++) { |
87 | if (olddata1[i]) { |
88 | p = olddata1[i]; |
89 | while (p) { |
90 | k1 = Hasher1::HashCode(p->Key1(),newBuck); |
91 | k2 = Hasher2::HashCode(p->Key2(),newBuck); |
92 | q = (TCollection_DoubleMapNode*) p->Next(); |
93 | p->Next() = newdata1[k1]; |
94 | p->Next2() = newdata2[k2]; |
95 | newdata1[k1] = p; |
96 | newdata2[k2] = p; |
97 | p = q; |
98 | } |
99 | } |
100 | } |
101 | } |
102 | EndResize(N,newBuck,newData1,newData2); |
103 | } |
104 | } |
105 | |
106 | //======================================================================= |
107 | //function : Clear |
108 | //purpose : |
109 | //======================================================================= |
110 | |
111 | void TCollection_DoubleMap::Clear() |
112 | { |
113 | if (!IsEmpty()) { |
114 | Standard_Integer i; |
115 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**) myData1; |
116 | // TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**) myData2; |
117 | TCollection_DoubleMapNode *p,*q; |
118 | for (i = 0; i <= NbBuckets(); i++) { |
119 | p = data1[i]; |
120 | while (p) { |
121 | q = (TCollection_DoubleMapNode*) p->Next(); |
122 | delete p; |
123 | p = q; |
124 | } |
125 | } |
126 | } |
127 | TCollection_BasicMap::Destroy(); |
128 | } |
129 | |
130 | //======================================================================= |
131 | //function : Bind |
132 | //purpose : |
133 | //======================================================================= |
134 | |
135 | void TCollection_DoubleMap::Bind(const TheKey1& K1, const TheKey2& K2) |
136 | { |
137 | if (Resizable()) ReSize(Extent()); |
138 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; |
139 | TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; |
140 | Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); |
141 | Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); |
142 | TCollection_DoubleMapNode* p; |
143 | p = data1[k1]; |
144 | while (p) { |
145 | if (Hasher1::IsEqual(p->Key1(),K1)) |
146 | Standard_MultiplyDefined::Raise("DoubleMap:Bind"); |
147 | p = (TCollection_DoubleMapNode*) p->Next(); |
148 | } |
149 | p = data2[k2]; |
150 | while (p) { |
151 | if (Hasher2::IsEqual(p->Key2(),K2)) |
152 | Standard_MultiplyDefined::Raise("DoubleMap:Bind"); |
153 | p = (TCollection_DoubleMapNode*)p->Next2(); |
154 | } |
155 | p = new TCollection_DoubleMapNode(K1,K2,data1[k1],data2[k2]); |
156 | data1[k1] = p; |
157 | data2[k2] = p; |
158 | Increment(); |
159 | } |
160 | |
161 | //======================================================================= |
162 | //function : AreBound |
163 | //purpose : |
164 | //======================================================================= |
165 | |
166 | Standard_Boolean TCollection_DoubleMap::AreBound(const TheKey1& K1, |
167 | const TheKey2& K2) const |
168 | { |
169 | if (IsEmpty()) return Standard_False; |
170 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; |
171 | TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; |
172 | Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); |
173 | Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); |
174 | TCollection_DoubleMapNode *p1, *p2; |
175 | p1 = data1[k1]; |
176 | while (p1) { |
177 | if (Hasher1::IsEqual(p1->Key1(),K1)) break; |
178 | p1 = (TCollection_DoubleMapNode*) p1->Next(); |
179 | } |
180 | if (p1 == NULL) return Standard_False; |
181 | p2 = data2[k2]; |
182 | while (p2) { |
183 | if (Hasher2::IsEqual(p2->Key2(),K2)) |
184 | break; |
185 | p2 = (TCollection_DoubleMapNode*)p2->Next2(); |
186 | } |
187 | if (p2 == NULL) return Standard_False; |
188 | return p1 == p2; |
189 | } |
190 | |
191 | //======================================================================= |
192 | //function : IsBound1 |
193 | //purpose : |
194 | //======================================================================= |
195 | |
196 | Standard_Boolean TCollection_DoubleMap::IsBound1(const TheKey1& K1) const |
197 | { |
198 | if (IsEmpty()) return Standard_False; |
199 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; |
200 | Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); |
201 | TCollection_DoubleMapNode *p1; |
202 | p1 = data1[k1]; |
203 | while (p1) { |
204 | if (Hasher1::IsEqual(p1->Key1(),K1)) return Standard_True; |
205 | p1 = (TCollection_DoubleMapNode*) p1->Next(); |
206 | } |
207 | return Standard_False; |
208 | } |
209 | |
210 | //======================================================================= |
211 | //function : IsBound2 |
212 | //purpose : |
213 | //======================================================================= |
214 | |
215 | Standard_Boolean TCollection_DoubleMap::IsBound2(const TheKey2& K2) const |
216 | { |
217 | if (IsEmpty()) return Standard_False; |
218 | TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; |
219 | Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); |
220 | TCollection_DoubleMapNode *p2; |
221 | p2 = data2[k2]; |
222 | while (p2) { |
223 | if (Hasher2::IsEqual(p2->Key2(),K2)) return Standard_True; |
224 | p2 = (TCollection_DoubleMapNode*)p2->Next2(); |
225 | } |
226 | return Standard_False; |
227 | } |
228 | |
229 | //======================================================================= |
230 | //function : Find1 |
231 | //purpose : |
232 | //======================================================================= |
233 | |
234 | const TheKey2& TCollection_DoubleMap::Find1(const TheKey1& K1) const |
235 | { |
236 | Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find1"); |
237 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; |
238 | Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); |
239 | TCollection_DoubleMapNode *p1; |
240 | p1 = data1[k1]; |
241 | while (p1) { |
242 | if (Hasher1::IsEqual(p1->Key1(),K1)) return p1->Key2(); |
243 | p1 = (TCollection_DoubleMapNode*) p1->Next(); |
244 | } |
245 | Standard_NoSuchObject::Raise("TCollection_DoubleMap::Find1"); |
246 | return p1->Key2(); |
247 | } |
248 | |
249 | //======================================================================= |
250 | //function : Find2 |
251 | //purpose : |
252 | //======================================================================= |
253 | |
254 | const TheKey1& TCollection_DoubleMap::Find2(const TheKey2& K2) const |
255 | { |
256 | Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find2"); |
257 | TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; |
258 | Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); |
259 | TCollection_DoubleMapNode *p2; |
260 | p2 = data2[k2]; |
261 | while (p2) { |
262 | if (Hasher2::IsEqual(p2->Key2(),K2)) return p2->Key1(); |
263 | p2 = (TCollection_DoubleMapNode*)p2->Next2(); |
264 | } |
265 | Standard_NoSuchObject::Raise("TCollection_DoubleMap::Find2"); |
266 | return p2->Key1(); |
267 | } |
268 | |
269 | //======================================================================= |
270 | //function : UnBind1 |
271 | //purpose : |
272 | //======================================================================= |
273 | |
274 | Standard_Boolean TCollection_DoubleMap::UnBind1(const TheKey1& K1) |
275 | { |
276 | if (IsEmpty()) return Standard_False; |
277 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; |
278 | TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; |
279 | Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); |
280 | Standard_Integer k2; |
281 | TCollection_DoubleMapNode *p1, *p2, *q1, *q2; |
282 | q1 = q2 = NULL; |
283 | p1 = data1[k1]; |
284 | while (p1) { |
285 | if (Hasher1::IsEqual(p1->Key1(),K1)) { |
286 | // remove from the first |
287 | if (q1) |
288 | q1->Next() = p1->Next(); |
289 | else |
290 | data1[k1] = (TCollection_DoubleMapNode*) p1->Next(); |
291 | // remove from the second |
292 | k2 = Hasher2::HashCode(p1->Key2(),NbBuckets()); |
293 | p2 = data2[k2]; |
294 | while (p2) { |
295 | if (p2 == p1) { |
296 | if (q2) |
297 | q2->Next2() = p2->Next2(); |
298 | else |
299 | data2[k2] = (TCollection_DoubleMapNode*)p2->Next2(); |
300 | break; |
301 | } |
302 | q2 = p2; |
303 | p2 = (TCollection_DoubleMapNode*)p2->Next2(); |
304 | } |
305 | delete p1; |
306 | Decrement(); |
307 | return Standard_True; |
308 | } |
309 | q1 = p1; |
310 | p1 = (TCollection_DoubleMapNode*) p1->Next(); |
311 | } |
312 | return Standard_False; |
313 | } |
314 | |
315 | //======================================================================= |
316 | //function : UnBind2 |
317 | //purpose : |
318 | //======================================================================= |
319 | |
320 | Standard_Boolean TCollection_DoubleMap::UnBind2(const TheKey2& K2) |
321 | { |
322 | if (IsEmpty()) return Standard_False; |
323 | TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; |
324 | TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; |
325 | Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); |
326 | Standard_Integer k1; |
327 | TCollection_DoubleMapNode *p1, *p2, *q1, *q2; |
328 | q1 = q2 = NULL; |
329 | p2 = data2[k2]; |
330 | while (p2) { |
331 | if (Hasher2::IsEqual(p2->Key2(),K2)) { |
332 | // remove from the second |
333 | if (q2) |
334 | q2->Next2() = p2->Next2(); |
335 | else |
336 | data2[k2] = (TCollection_DoubleMapNode*)p2->Next2(); |
337 | // remove from the first |
338 | k1 = Hasher1::HashCode(p2->Key1(),NbBuckets()); |
339 | p1 = data1[k1]; |
340 | while (p1) { |
341 | if (p2 == p1) { |
342 | if (q1) |
343 | q1->Next() = p1->Next(); |
344 | else |
345 | data1[k1] = (TCollection_DoubleMapNode*) p1->Next(); |
346 | break; |
347 | } |
348 | q1 = p1; |
349 | p1 = (TCollection_DoubleMapNode*) p1->Next(); |
350 | } |
351 | delete p2; |
352 | Decrement(); |
353 | return Standard_True; |
354 | } |
355 | q2 = p2; |
356 | p2 = (TCollection_DoubleMapNode*)p2->Next2(); |
357 | } |
358 | return Standard_False; |
359 | } |
360 | |
361 | // method of the iterator |
362 | |
363 | //======================================================================= |
364 | //function : Key1 |
365 | //purpose : |
366 | //======================================================================= |
367 | |
368 | const TheKey1& TCollection_DoubleMapIterator::Key1() const |
369 | { |
370 | Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key1"); |
371 | return ((TCollection_DoubleMapNode*) myNode)->Key1(); |
372 | } |
373 | |
374 | //======================================================================= |
375 | //function : Key2 |
376 | //purpose : |
377 | //======================================================================= |
378 | |
379 | const TheKey2& TCollection_DoubleMapIterator::Key2() const |
380 | { |
381 | Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key2"); |
382 | return ((TCollection_DoubleMapNode*) myNode)->Key2(); |
383 | } |