xref: /trunk/main/tools/source/memtools/unqidx.cxx (revision 79aad27f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_tools.hxx"
26 #include <impcont.hxx>
27 #include <tools/unqidx.hxx>
28 #include <tools/unqid.hxx>
29 
30 /*************************************************************************
31 |*
32 |*    UniqueIndex::UniqueIndex()
33 |*
34 |*    Beschreibung      UNQIDX.SDW
35 |*    Ersterstellung    TH 24.09.91
36 |*    Letzte Aenderung  TH 24.09.91
37 |*
38 *************************************************************************/
39 
UniqueIndex(sal_uIntPtr _nStartIndex,sal_uIntPtr _nInitSize,sal_uIntPtr _nReSize)40 UniqueIndex::UniqueIndex( sal_uIntPtr _nStartIndex,
41                           sal_uIntPtr _nInitSize, sal_uIntPtr _nReSize ) :
42                  Container( _nInitSize )
43 {
44     nReSize     	= _nReSize;
45     nStartIndex 	= _nStartIndex;
46     nUniqIndex  	= 0;
47     nCount      	= 0;
48 }
49 
50 /*************************************************************************
51 |*
52 |*    UniqueIndex::UniqueIndex()
53 |*
54 |*    Beschreibung      UNQIDX.SDW
55 |*    Ersterstellung    TH 24.09.91
56 |*    Letzte Aenderung  TH 24.09.91
57 |*
58 *************************************************************************/
59 
UniqueIndex(const UniqueIndex & rIdx)60 UniqueIndex::UniqueIndex( const UniqueIndex& rIdx ) :
61                  Container( rIdx )
62 {
63     nReSize     = rIdx.nReSize;
64     nStartIndex = rIdx.nStartIndex;
65     nUniqIndex  = rIdx.nUniqIndex;
66     nCount      = rIdx.nCount;
67 }
68 
69 /*************************************************************************
70 |*
71 |*    UniqueIndex::Insert()
72 |*
73 |*    Beschreibung      UNQIDX.SDW
74 |*    Ersterstellung    TH 24.09.91
75 |*    Letzte Aenderung  TH 24.09.91
76 |*
77 *************************************************************************/
78 
Insert(void * p)79 sal_uIntPtr UniqueIndex::Insert( void* p )
80 {
81     // NULL-Pointer ist nicht erlaubt
82     if ( !p )
83         return UNIQUEINDEX_ENTRY_NOTFOUND;
84 
85     // Ist Array voll, dann expandieren
86     if ( nCount == Container::GetSize() )
87         SetSize( nCount + nReSize );
88 
89     // Damit UniqIndex nicht ueberlaeuft, wenn Items geloescht wurden
90     nUniqIndex = nUniqIndex % Container::GetSize();
91 
92     // Leeren Eintrag suchen
93     while ( Container::ImpGetObject( nUniqIndex ) != NULL )
94         nUniqIndex = (nUniqIndex+1) % Container::GetSize();
95 
96     // Object im Array speichern
97     Container::Replace( p, nUniqIndex );
98 
99     // Anzahl der Eintraege erhoehen und Index zurueckgeben
100     nCount++;
101     nUniqIndex++;
102     return ( nUniqIndex + nStartIndex - 1 );
103 }
104 
105 /*************************************************************************
106 |*
107 |*    UniqueIndex::Insert()
108 |*
109 |*    Beschreibung      UNQIDX.SDW
110 |*    Ersterstellung    MM 21.04.96
111 |*    Letzte Aenderung  MM 21.04.96
112 |*
113 *************************************************************************/
114 
Insert(sal_uIntPtr nIndex,void * p)115 sal_uIntPtr UniqueIndex::Insert( sal_uIntPtr nIndex, void* p )
116 {
117     // NULL-Pointer ist nicht erlaubt
118     if ( !p )
119         return UNIQUEINDEX_ENTRY_NOTFOUND;
120 
121 	sal_uIntPtr nContIndex = nIndex - nStartIndex;
122     // Ist Array voll, dann expandieren
123     if ( nContIndex >= Container::GetSize() )
124         SetSize( nContIndex + nReSize );
125 
126     // Object im Array speichern
127     Container::Replace( p, nContIndex );
128 
129     // Anzahl der Eintraege erhoehen und Index zurueckgeben
130     nCount++;
131     return nIndex;
132 }
133 
134 /*************************************************************************
135 |*
136 |*    UniqueIndex::Remove()
137 |*
138 |*    Beschreibung      UNQIDX.SDW
139 |*    Ersterstellung    TH 24.09.91
140 |*    Letzte Aenderung  TH 24.09.91
141 |*
142 *************************************************************************/
143 
Remove(sal_uIntPtr nIndex)144 void* UniqueIndex::Remove( sal_uIntPtr nIndex )
145 {
146     // Ist Index zulaessig
147     if ( (nIndex >= nStartIndex) &&
148          (nIndex < (Container::GetSize()+nStartIndex)) )
149     {
150         // Index-Eintrag als leeren Eintrag setzen und Anzahl der
151         // gespeicherten Indexe erniedriegen, wenn Eintrag belegt war
152         void* p = Container::Replace( NULL, nIndex-nStartIndex );
153         if ( p )
154             nCount--;
155         return p;
156     }
157     else
158         return NULL;
159 }
160 
161 /*************************************************************************
162 |*
163 |*    UniqueIndex::Replace()
164 |*
165 |*    Beschreibung      UNQIDX.SDW
166 |*    Ersterstellung    TH 24.09.91
167 |*    Letzte Aenderung  TH 24.09.91
168 |*
169 *************************************************************************/
170 
Replace(sal_uIntPtr nIndex,void * p)171 void* UniqueIndex::Replace( sal_uIntPtr nIndex, void* p )
172 {
173     // NULL-Pointer ist nicht erlaubt
174     if ( !p )
175         return NULL;
176 
177     // Ist Index zulaessig
178     if ( IsIndexValid( nIndex ) )
179     {
180         // Index-Eintrag ersetzen und alten zurueckgeben
181         return Container::Replace( p, nIndex-nStartIndex );
182     }
183     else
184         return NULL;
185 }
186 
187 /*************************************************************************
188 |*
189 |*    UniqueIndex::Get()
190 |*
191 |*    Beschreibung      UNQIDX.SDW
192 |*    Ersterstellung    TH 24.09.91
193 |*    Letzte Aenderung  TH 24.09.91
194 |*
195 *************************************************************************/
196 
Get(sal_uIntPtr nIndex) const197 void* UniqueIndex::Get( sal_uIntPtr nIndex ) const
198 {
199     // Ist Index zulaessig
200     if ( (nIndex >= nStartIndex) &&
201          (nIndex < (Container::GetSize()+nStartIndex)) )
202         return Container::ImpGetObject( nIndex-nStartIndex );
203     else
204         return NULL;
205 }
206 
207 /*************************************************************************
208 |*
209 |*    UniqueIndex::GetCurIndex()
210 |*
211 |*    Beschreibung      UNQIDX.SDW
212 |*    Ersterstellung    TH 24.09.91
213 |*    Letzte Aenderung  TH 24.09.91
214 |*
215 *************************************************************************/
216 
GetCurIndex() const217 sal_uIntPtr UniqueIndex::GetCurIndex() const
218 {
219     sal_uIntPtr nPos = Container::GetCurPos();
220 
221     // Ist der Current-Index nicht belegt, dann gibt es keinen Current-Index
222     if ( !Container::ImpGetObject( nPos ) )
223         return UNIQUEINDEX_ENTRY_NOTFOUND;
224     else
225         return nPos+nStartIndex;
226 }
227 
228 /*************************************************************************
229 |*
230 |*    UniqueIndex::GetIndex()
231 |*
232 |*    Beschreibung      UNQIDX.SDW
233 |*    Ersterstellung    TH 24.09.91
234 |*    Letzte Aenderung  TH 24.09.91
235 |*
236 *************************************************************************/
237 
GetIndex(const void * p) const238 sal_uIntPtr UniqueIndex::GetIndex( const void* p ) const
239 {
240     // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
241     if ( !p )
242         return UNIQUEINDEX_ENTRY_NOTFOUND;
243 
244     sal_uIntPtr nIndex = Container::GetPos( p );
245 
246     if ( nIndex != CONTAINER_ENTRY_NOTFOUND )
247         return nIndex+nStartIndex;
248     else
249         return UNIQUEINDEX_ENTRY_NOTFOUND;
250 }
251 
252 /*************************************************************************
253 |*
254 |*    UniqueIndex::IsIndexValid()
255 |*
256 |*    Beschreibung      UNQIDX.SDW
257 |*    Ersterstellung    TH 24.09.91
258 |*    Letzte Aenderung  TH 24.09.91
259 |*
260 *************************************************************************/
261 
IsIndexValid(sal_uIntPtr nIndex) const262 sal_Bool UniqueIndex::IsIndexValid( sal_uIntPtr nIndex ) const
263 {
264     // Ist Index zulaessig
265     if ( (nIndex >= nStartIndex) &&
266          (nIndex < (Container::GetSize()+nStartIndex)) )
267     {
268         // Index ist nur zulaessig, wenn Eintrag auch belegt ist
269         if ( Container::ImpGetObject( nIndex-nStartIndex ) )
270             return sal_True;
271         else
272             return sal_False;
273     }
274     else
275         return sal_False;
276 }
277 
278 /*************************************************************************
279 |*
280 |*    UniqueIndex::Seek()
281 |*
282 |*    Beschreibung      UNQIDX.SDW
283 |*    Ersterstellung    TH 24.09.91
284 |*    Letzte Aenderung  TH 24.09.91
285 |*
286 *************************************************************************/
287 
Seek(sal_uIntPtr nIndex)288 void* UniqueIndex::Seek( sal_uIntPtr nIndex )
289 {
290     // Index-Eintrag als aktuellen setzten, wenn er gueltig ist
291     if ( IsIndexValid( nIndex ) )
292         return Container::Seek( nIndex-nStartIndex );
293     else
294         return NULL;
295 }
296 
297 /*************************************************************************
298 |*
299 |*    UniqueIndex::Seek()
300 |*
301 |*    Beschreibung      UNQIDX.SDW
302 |*    Ersterstellung    TH 24.09.91
303 |*    Letzte Aenderung  TH 24.09.91
304 |*
305 *************************************************************************/
306 
Seek(void * p)307 void* UniqueIndex::Seek( void* p )
308 {
309     // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden
310     if ( !p )
311         return NULL;
312 
313     sal_uIntPtr nIndex = GetIndex( p );
314 
315     // Ist Index vorhanden, dann als aktuellen Eintrag setzen
316     if ( nIndex != UNIQUEINDEX_ENTRY_NOTFOUND )
317         return Container::Seek( nIndex-nStartIndex );
318     else
319         return NULL;
320 }
321 
322 /*************************************************************************
323 |*
324 |*    UniqueIndex::First()
325 |*
326 |*    Beschreibung      UNQIDX.SDW
327 |*    Ersterstellung    TH 24.09.91
328 |*    Letzte Aenderung  TH 24.09.91
329 |*
330 *************************************************************************/
331 
First()332 void* UniqueIndex::First()
333 {
334     void* p = Container::First();
335 
336     while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) )
337         p = Container::Next();
338 
339     return p;
340 }
341 
342 /*************************************************************************
343 |*
344 |*    UniqueIndex::Last()
345 |*
346 |*    Beschreibung      UNQIDX.SDW
347 |*    Ersterstellung    TH 24.09.91
348 |*    Letzte Aenderung  TH 24.09.91
349 |*
350 *************************************************************************/
351 
Last()352 void* UniqueIndex::Last()
353 {
354     void* p = Container::Last();
355 
356     while ( !p && Container::GetCurPos() )
357         p = Container::Prev();
358 
359     return p;
360 }
361 
362 /*************************************************************************
363 |*
364 |*    UniqueIndex::Next()
365 |*
366 |*    Beschreibung      UNQIDX.SDW
367 |*    Ersterstellung    TH 24.09.91
368 |*    Letzte Aenderung  TH 24.09.91
369 |*
370 *************************************************************************/
371 
Next()372 void* UniqueIndex::Next()
373 {
374     void* p = NULL;
375 
376     while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) )
377         p = Container::Next();
378 
379     return p;
380 }
381 
382 /*************************************************************************
383 |*
384 |*    UniqueIndex::Prev()
385 |*
386 |*    Beschreibung      UNQIDX.SDW
387 |*    Ersterstellung    TH 24.09.91
388 |*    Letzte Aenderung  TH 24.09.91
389 |*
390 *************************************************************************/
391 
Prev()392 void* UniqueIndex::Prev()
393 {
394     void* p = NULL;
395 
396     while ( !p && Container::GetCurPos() )
397         p = Container::Prev();
398 
399     return p;
400 }
401 
402 /*************************************************************************
403 |*
404 |*    UniqueIndex::operator =()
405 |*
406 |*    Beschreibung      UNQIDX.SDW
407 |*    Ersterstellung    TH 24.09.91
408 |*    Letzte Aenderung  TH 24.09.91
409 |*
410 *************************************************************************/
411 
operator =(const UniqueIndex & rIdx)412 UniqueIndex& UniqueIndex::operator =( const UniqueIndex& rIdx )
413 {
414     // Neue Werte zuweisen
415     Container::operator =( rIdx );
416     nReSize     = rIdx.nReSize;
417     nStartIndex = rIdx.nStartIndex;
418     nUniqIndex  = rIdx.nUniqIndex;
419     nCount      = rIdx.nCount;
420     return *this;
421 }
422 
423 /*************************************************************************
424 |*
425 |*    UniqueIndex::operator ==()
426 |*
427 |*    Beschreibung      UNQIDX.SDW
428 |*    Ersterstellung    TH 24.09.91
429 |*    Letzte Aenderung  TH 24.09.91
430 |*
431 *************************************************************************/
432 
operator ==(const UniqueIndex & rIdx) const433 sal_Bool UniqueIndex::operator ==( const UniqueIndex& rIdx ) const
434 {
435     // Neue Werte zuweisen
436     if ( (nStartIndex == rIdx.nStartIndex) &&
437          (nCount      == rIdx.nCount)      &&
438          (Container::operator ==( rIdx )) )
439         return sal_True;
440     else
441         return sal_False;
442 }
443 /*************************************************************************
444 |*
445 |*    UniqueIdContainer::UniqueIdContainer ()
446 |*
447 |*    Beschreibung      UNQIDX.SDW
448 |*    Ersterstellung    MM 29.04.96
449 |*    Letzte Aenderung  MM 29.04.96
450 |*
451 *************************************************************************/
452 
UniqueIdContainer(const UniqueIdContainer & rObj)453 UniqueIdContainer::UniqueIdContainer( const UniqueIdContainer& rObj )
454 	: UniqueIndex( rObj )
455 	, nCollectCount( rObj.nCollectCount )
456 {
457     sal_uIntPtr nCur = GetCurIndex();
458 
459     ImpUniqueId * pEle = (ImpUniqueId *)First();
460     while( pEle )
461     {
462         pEle->nRefCount++;
463         pEle = (ImpUniqueId *)Next();
464     }
465     Seek( nCur );
466 }
467 
468 /*************************************************************************
469 |*
470 |*    UniqueIdContainer::operator = ()
471 |*
472 |*    Beschreibung      UNQIDX.SDW
473 |*    Ersterstellung    MM 01.08.94
474 |*    Letzte Aenderung  MM 01.08.94
475 |*
476 *************************************************************************/
477 
operator =(const UniqueIdContainer & rObj)478 UniqueIdContainer& UniqueIdContainer::operator = ( const UniqueIdContainer & rObj )
479 {
480     UniqueIndex::operator = ( rObj );
481 	nCollectCount = rObj.nCollectCount;
482 
483     sal_uIntPtr nCur = GetCurIndex();
484 
485     ImpUniqueId * pEle = (ImpUniqueId *)First();
486     while( pEle )
487     {
488         pEle->nRefCount++;
489         pEle = (ImpUniqueId *)Next();
490     }
491     Seek( nCur );
492     return *this;
493 }
494 
495 /*************************************************************************
496 |*
497 |*    UniqueIdContainer::Clear()
498 |*
499 |*    Beschreibung      UNQIDX.SDW
500 |*    Ersterstellung    MM 01.08.94
501 |*    Letzte Aenderung  MM 01.08.94
502 |*
503 *************************************************************************/
504 
Clear(sal_Bool bAll)505 void UniqueIdContainer::Clear( sal_Bool bAll )
506 {
507     sal_uInt16 nFree = bAll ? 0xFFFF : 1;
508 
509     ImpUniqueId* pId = (ImpUniqueId*)Last();
510     sal_Bool bLast = sal_True;
511     while ( pId )
512     {
513         if ( pId->nRefCount <= nFree )
514         {
515             ((ImpUniqueId *)Remove( pId->nId ))->Release();
516             if( bLast )
517                 pId = (ImpUniqueId *)Last();
518             else
519                 pId = (ImpUniqueId *)Prev();
520         }
521         else
522         {
523             pId = (ImpUniqueId *)Prev();
524             bLast = sal_False;
525         }
526     }
527 }
528 
529 /*************************************************************************
530 |*
531 |*    UniqueIdContainer::CreateId()
532 |*
533 |*    Beschreibung      UNQIDX.SDW
534 |*    Ersterstellung    MM 01.08.94
535 |*    Letzte Aenderung  MM 01.08.94
536 |*
537 *************************************************************************/
538 
CreateId()539 UniqueItemId UniqueIdContainer::CreateId()
540 {
541     if( nCollectCount > 50 )
542     { // aufraeumen
543         Clear( sal_False );
544         nCollectCount = 0;
545     }
546     nCollectCount++;
547 
548     ImpUniqueId * pId = new ImpUniqueId;
549     pId->nRefCount = 1;
550     pId->nId = Insert( pId );
551     return UniqueItemId( pId );
552 }
553 
554 /*************************************************************************
555 |*
556 |*    UniqueIdContainer::CreateIdProt()
557 |*
558 |*    Beschreibung      UNQIDX.SDW
559 |*    Ersterstellung    MM 01.08.94
560 |*    Letzte Aenderung  MM 01.08.94
561 |*
562 *************************************************************************/
563 
CreateFreeId(sal_uIntPtr nId)564 UniqueItemId UniqueIdContainer::CreateFreeId( sal_uIntPtr nId )
565 {
566     // Einfach erzeugen, fuer abgeleitete Klasse
567     ImpUniqueId * pId = new ImpUniqueId;
568     pId->nRefCount = 0;
569     pId->nId = nId;
570     return UniqueItemId( pId );
571 }
572 
573 /*************************************************************************
574 |*
575 |*    UniqueIdContainer::CreateIdProt()
576 |*
577 |*    Beschreibung      UNQIDX.SDW
578 |*    Ersterstellung    MM 01.08.94
579 |*    Letzte Aenderung  MM 01.08.94
580 |*
581 *************************************************************************/
582 
CreateIdProt(sal_uIntPtr nId)583 UniqueItemId UniqueIdContainer::CreateIdProt( sal_uIntPtr nId )
584 {
585     if ( IsIndexValid( nId ) )
586         return UniqueItemId( (ImpUniqueId *)Get( nId ) );
587 
588     ImpUniqueId * pId;
589     do
590     {
591         pId = new ImpUniqueId;
592         pId->nRefCount = 1;
593         pId->nId = Insert( pId );
594     }
595     while( pId->nId != nId );
596     return UniqueItemId( pId );
597 }
598