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