// Created on: 1993-01-08 // Created by: Remi LEQUETTE // Copyright (c) 1993-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include //======================================================================= //function : TCollection_DoubleMap //purpose : //======================================================================= TCollection_DoubleMap::TCollection_DoubleMap(const Standard_Integer NbBuckets): TCollection_BasicMap(NbBuckets,Standard_False) { } //======================================================================= //function : TCollection_DoubleMap //purpose : //======================================================================= TCollection_DoubleMap::TCollection_DoubleMap (const TCollection_DoubleMap& Other) : TCollection_BasicMap(Other.NbBuckets(),Standard_False) { if (Other.Extent() != 0) Standard_DomainError::Raise("TCollection:Copy of DoubleMap"); } //======================================================================= //function : Assign //purpose : //======================================================================= TCollection_DoubleMap& TCollection_DoubleMap::Assign (const TCollection_DoubleMap& Other) { if (this == &Other) return *this; Clear(); // ReSize(Other.NbBuckets()); if (!Other.IsEmpty()) { ReSize(Other.Extent()); for (TCollection_DoubleMapIterator It(Other); It.More(); It.Next()) { Bind(It.Key1(),It.Key2()); } } return *this; } //======================================================================= //function : ReSize //purpose : //======================================================================= void TCollection_DoubleMap::ReSize(const Standard_Integer N) { Standard_Integer newBuck; Standard_Address newData1=NULL, newData2=NULL; if (BeginResize(N,newBuck,newData1,newData2)) { if (myData1) { TCollection_DoubleMapNode** newdata1 = (TCollection_DoubleMapNode**) newData1; TCollection_DoubleMapNode** newdata2 = (TCollection_DoubleMapNode**) newData2; TCollection_DoubleMapNode** olddata1 = (TCollection_DoubleMapNode**) myData1; TCollection_DoubleMapNode *p, *q; Standard_Integer i,k1,k2; for (i = 0; i <= NbBuckets(); i++) { if (olddata1[i]) { p = olddata1[i]; while (p) { k1 = Hasher1::HashCode(p->Key1(),newBuck); k2 = Hasher2::HashCode(p->Key2(),newBuck); q = (TCollection_DoubleMapNode*) p->Next(); p->Next() = newdata1[k1]; p->Next2() = newdata2[k2]; newdata1[k1] = p; newdata2[k2] = p; p = q; } } } } EndResize(N,newBuck,newData1,newData2); } } //======================================================================= //function : Clear //purpose : //======================================================================= void TCollection_DoubleMap::Clear() { if (!IsEmpty()) { Standard_Integer i; TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**) myData1; // TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**) myData2; TCollection_DoubleMapNode *p,*q; for (i = 0; i <= NbBuckets(); i++) { p = data1[i]; while (p) { q = (TCollection_DoubleMapNode*) p->Next(); delete p; p = q; } } } TCollection_BasicMap::Destroy(); } //======================================================================= //function : Bind //purpose : //======================================================================= void TCollection_DoubleMap::Bind(const TheKey1& K1, const TheKey2& K2) { if (Resizable()) ReSize(Extent()); TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); TCollection_DoubleMapNode* p; p = data1[k1]; while (p) { if (Hasher1::IsEqual(p->Key1(),K1)) Standard_MultiplyDefined::Raise("DoubleMap:Bind"); p = (TCollection_DoubleMapNode*) p->Next(); } p = data2[k2]; while (p) { if (Hasher2::IsEqual(p->Key2(),K2)) Standard_MultiplyDefined::Raise("DoubleMap:Bind"); p = (TCollection_DoubleMapNode*)p->Next2(); } p = new TCollection_DoubleMapNode(K1,K2,data1[k1],data2[k2]); data1[k1] = p; data2[k2] = p; Increment(); } //======================================================================= //function : AreBound //purpose : //======================================================================= Standard_Boolean TCollection_DoubleMap::AreBound(const TheKey1& K1, const TheKey2& K2) const { if (IsEmpty()) return Standard_False; TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); TCollection_DoubleMapNode *p1, *p2; p1 = data1[k1]; while (p1) { if (Hasher1::IsEqual(p1->Key1(),K1)) break; p1 = (TCollection_DoubleMapNode*) p1->Next(); } if (p1 == NULL) return Standard_False; p2 = data2[k2]; while (p2) { if (Hasher2::IsEqual(p2->Key2(),K2)) break; p2 = (TCollection_DoubleMapNode*)p2->Next2(); } if (p2 == NULL) return Standard_False; return p1 == p2; } //======================================================================= //function : IsBound1 //purpose : //======================================================================= Standard_Boolean TCollection_DoubleMap::IsBound1(const TheKey1& K1) const { if (IsEmpty()) return Standard_False; TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); TCollection_DoubleMapNode *p1; p1 = data1[k1]; while (p1) { if (Hasher1::IsEqual(p1->Key1(),K1)) return Standard_True; p1 = (TCollection_DoubleMapNode*) p1->Next(); } return Standard_False; } //======================================================================= //function : IsBound2 //purpose : //======================================================================= Standard_Boolean TCollection_DoubleMap::IsBound2(const TheKey2& K2) const { if (IsEmpty()) return Standard_False; TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); TCollection_DoubleMapNode *p2; p2 = data2[k2]; while (p2) { if (Hasher2::IsEqual(p2->Key2(),K2)) return Standard_True; p2 = (TCollection_DoubleMapNode*)p2->Next2(); } return Standard_False; } //======================================================================= //function : Find1 //purpose : //======================================================================= const TheKey2& TCollection_DoubleMap::Find1(const TheKey1& K1) const { Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find1"); TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); TCollection_DoubleMapNode *p1; p1 = data1[k1]; while (p1) { if (Hasher1::IsEqual(p1->Key1(),K1)) return p1->Key2(); p1 = (TCollection_DoubleMapNode*) p1->Next(); } Standard_NoSuchObject::Raise("TCollection_DoubleMap::Find1"); return p1->Key2(); } //======================================================================= //function : Find2 //purpose : //======================================================================= const TheKey1& TCollection_DoubleMap::Find2(const TheKey2& K2) const { Standard_NoSuchObject_Raise_if(IsEmpty(),"TCollection_DoubleMap::Find2"); TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); TCollection_DoubleMapNode *p2; p2 = data2[k2]; while (p2) { if (Hasher2::IsEqual(p2->Key2(),K2)) return p2->Key1(); p2 = (TCollection_DoubleMapNode*)p2->Next2(); } Standard_NoSuchObject::Raise("TCollection_DoubleMap::Find2"); return p2->Key1(); } //======================================================================= //function : UnBind1 //purpose : //======================================================================= Standard_Boolean TCollection_DoubleMap::UnBind1(const TheKey1& K1) { if (IsEmpty()) return Standard_False; TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; Standard_Integer k1 = Hasher1::HashCode(K1,NbBuckets()); Standard_Integer k2; TCollection_DoubleMapNode *p1, *p2, *q1, *q2; q1 = q2 = NULL; p1 = data1[k1]; while (p1) { if (Hasher1::IsEqual(p1->Key1(),K1)) { // remove from the first if (q1) q1->Next() = p1->Next(); else data1[k1] = (TCollection_DoubleMapNode*) p1->Next(); // remove from the second k2 = Hasher2::HashCode(p1->Key2(),NbBuckets()); p2 = data2[k2]; while (p2) { if (p2 == p1) { if (q2) q2->Next2() = p2->Next2(); else data2[k2] = (TCollection_DoubleMapNode*)p2->Next2(); break; } q2 = p2; p2 = (TCollection_DoubleMapNode*)p2->Next2(); } delete p1; Decrement(); return Standard_True; } q1 = p1; p1 = (TCollection_DoubleMapNode*) p1->Next(); } return Standard_False; } //======================================================================= //function : UnBind2 //purpose : //======================================================================= Standard_Boolean TCollection_DoubleMap::UnBind2(const TheKey2& K2) { if (IsEmpty()) return Standard_False; TCollection_DoubleMapNode** data1 = (TCollection_DoubleMapNode**)myData1; TCollection_DoubleMapNode** data2 = (TCollection_DoubleMapNode**)myData2; Standard_Integer k2 = Hasher2::HashCode(K2,NbBuckets()); Standard_Integer k1; TCollection_DoubleMapNode *p1, *p2, *q1, *q2; q1 = q2 = NULL; p2 = data2[k2]; while (p2) { if (Hasher2::IsEqual(p2->Key2(),K2)) { // remove from the second if (q2) q2->Next2() = p2->Next2(); else data2[k2] = (TCollection_DoubleMapNode*)p2->Next2(); // remove from the first k1 = Hasher1::HashCode(p2->Key1(),NbBuckets()); p1 = data1[k1]; while (p1) { if (p2 == p1) { if (q1) q1->Next() = p1->Next(); else data1[k1] = (TCollection_DoubleMapNode*) p1->Next(); break; } q1 = p1; p1 = (TCollection_DoubleMapNode*) p1->Next(); } delete p2; Decrement(); return Standard_True; } q2 = p2; p2 = (TCollection_DoubleMapNode*)p2->Next2(); } return Standard_False; } // method of the iterator //======================================================================= //function : Key1 //purpose : //======================================================================= const TheKey1& TCollection_DoubleMapIterator::Key1() const { Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key1"); return ((TCollection_DoubleMapNode*) myNode)->Key1(); } //======================================================================= //function : Key2 //purpose : //======================================================================= const TheKey2& TCollection_DoubleMapIterator::Key2() const { Standard_NoSuchObject_Raise_if(!More(),"TCollection_DoubleMapIterator::Key2"); return ((TCollection_DoubleMapNode*) myNode)->Key2(); }