0024911: Avoid using virtual functions in NCollection classes
[occt.git] / src / NCollection / NCollection_BaseMap.cxx
1 // Created on: 2002-04-18
2 // Created by: Alexander KARTOMIN (akm)
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 // Purpose:     Implementation of the BaseMap class
17
18 #include <NCollection_BaseMap.hxx>
19 #include <TCollection.hxx>
20
21 //=======================================================================
22 //function : BeginResize
23 //purpose  : 
24 //=======================================================================
25
26 Standard_Boolean  NCollection_BaseMap::BeginResize
27   (const Standard_Integer  NbBuckets,
28    Standard_Integer&       N,
29    NCollection_ListNode**& data1,
30    NCollection_ListNode**& data2) const 
31 {
32   if (mySaturated) return Standard_False;
33   N = NextPrimeForMap(NbBuckets);
34   if (N <= myNbBuckets) {
35     if (!myData1)
36       N = myNbBuckets;
37     else
38       return Standard_False;
39   }
40   data1 = (NCollection_ListNode **)
41     myAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
42   memset(data1, 0, (N+1)*sizeof(NCollection_ListNode *));
43   if (isDouble) 
44   {
45     data2 = (NCollection_ListNode **)
46     myAllocator->Allocate((N+1)*sizeof(NCollection_ListNode *));
47     memset(data2, 0, (N+1)*sizeof(NCollection_ListNode *));
48   }
49   else
50     data2 = NULL;
51   return Standard_True;
52 }
53
54 //=======================================================================
55 //function : EndResize
56 //purpose  : 
57 //=======================================================================
58
59 void  NCollection_BaseMap::EndResize
60   (const Standard_Integer NbBuckets,
61    const Standard_Integer N,
62    NCollection_ListNode** data1,
63    NCollection_ListNode** data2)
64 {
65   if (myData1) 
66     myAllocator->Free(myData1);
67   if (myData2) 
68     myAllocator->Free(myData2);
69   myNbBuckets = N;
70   mySaturated = (myNbBuckets <= NbBuckets);
71   myData1 = data1;
72   myData2 = data2;
73 }
74
75
76 //=======================================================================
77 //function : Destroy
78 //purpose  : 
79 //=======================================================================
80
81 void  NCollection_BaseMap::Destroy (NCollection_DelMapNode fDel,
82                                     Standard_Boolean doReleaseMemory)
83 {
84   if (!IsEmpty()) 
85   {
86     Standard_Integer i;
87     NCollection_ListNode** data = (NCollection_ListNode**) myData1;
88     NCollection_ListNode *p,*q;
89     for (i = 0; i <= NbBuckets(); i++) 
90     {
91       if (data[i]) 
92       {
93         p = data[i];
94         while (p) 
95         {
96           q = (NCollection_ListNode*)p->Next();
97           fDel (p, myAllocator);
98           p = q;
99         }
100         data[i] = NULL;
101       }
102     }
103   }
104
105   mySize = 0;
106   if (doReleaseMemory)
107   {
108     mySaturated = Standard_False;
109     if (myData1) 
110       myAllocator->Free(myData1);
111     if (isDouble && myData2) 
112       myAllocator->Free(myData2);
113     myData1 = myData2 = NULL;
114   }
115 }
116
117
118 //=======================================================================
119 //function : Statistics
120 //purpose  : 
121 //=======================================================================
122
123 void NCollection_BaseMap::Statistics(Standard_OStream& S) const
124 {
125   S <<"\nMap Statistics\n---------------\n\n";
126   S <<"This Map has "<<myNbBuckets<<" Buckets and "<<mySize<<" Keys\n\n";
127   if (mySaturated) S<<"The maximum number of Buckets is reached\n";
128   
129   if (mySize == 0) return;
130
131   // compute statistics on 1
132   Standard_Integer * sizes = new Standard_Integer [mySize+1];
133   Standard_Integer i,l,nb;
134   NCollection_ListNode* p;
135   NCollection_ListNode** data;
136   
137   S << "\nStatistics for the first Key\n";
138   for (i = 0; i <= mySize; i++) sizes[i] = 0;
139   data = (NCollection_ListNode **) myData1;
140   nb = 0;
141   for (i = 0; i <= myNbBuckets; i++) 
142   {
143     l = 0;
144     p = data[i];
145     if (p) nb++;
146     while (p) 
147     {
148       l++;
149       p = p->Next();
150     }
151     sizes[l]++;
152   }
153
154   // display results
155   l = 0;
156   for (i = 0; i<= mySize; i++) 
157   {
158     if (sizes[i] > 0) 
159     {
160       l += sizes[i] * i;
161       S << setw(5) << sizes[i] <<" buckets of size "<<i<<"\n";
162     }
163   }
164
165   Standard_Real mean = ((Standard_Real) l) / ((Standard_Real) nb);
166   S<<"\n\nMean of length : "<<mean<<"\n";
167
168   delete [] sizes;
169 }
170
171 //=======================================================================
172 //function : NextPrimeForMap
173 //purpose  : 
174 //=======================================================================
175
176 Standard_Integer NCollection_BaseMap::NextPrimeForMap
177   (const Standard_Integer N) const
178 {
179   return TCollection::NextPrimeForMap ( N );
180 }
181