source: NonGTP/Xerces/xerces-c_2_8_0/include/xercesc/util/NameIdPool.hpp @ 2674

Revision 2674, 9.1 KB checked in by mattausch, 16 years ago (diff)
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: NameIdPool.hpp 568078 2007-08-21 11:43:25Z amassari $
20 */
21
22
23#if !defined(NAMEIDPOOL_HPP)
24#define NAMEIDPOOL_HPP
25
26#include <xercesc/util/XMemory.hpp>
27#include <xercesc/util/XMLString.hpp>
28#include <xercesc/util/PlatformUtils.hpp>
29
30XERCES_CPP_NAMESPACE_BEGIN
31
32//
33//  Forward declare the enumerator so he can be our friend. Can you say
34//  friend? Sure...
35//
36template <class TElem> class NameIdPoolEnumerator;
37
38
39//
40//  This class is provided to serve as the basis of many of the pools that
41//  are used by the scanner and validators. They often need to be able to
42//  store objects in such a way that they can be quickly accessed by the
43//  name field of the object, and such that each element added is assigned
44//  a unique id via which it can be accessed almost instantly.
45//
46//  Object names are enforced as being unique, since that's what all these
47//  pools require. So its effectively a hash table in conjunction with an
48//  array of references into the hash table by id. Ids are assigned such that
49//  id N can be used to get the Nth element from the array of references.
50//  This provides very fast access by id.
51//
52//  The way these pools are used, elements are never removed except when the
53//  whole thing is flushed. This makes it very easy to maintain the two
54//  access methods in sync.
55//
56//  For efficiency reasons, the id refererence array is never flushed until
57//  the dtor. This way, it does not have to be regrown every time its reused.
58//
59//  All elements are assumed to be owned by the pool!
60//
61//  We have to have a bucket element structure to use to maintain the linked
62//  lists for each bucket. Because some of the compilers we have to support
63//  are totally brain dead, it cannot be a nested class as it should be.
64//
65template <class TElem> struct NameIdPoolBucketElem
66{
67public :
68    NameIdPoolBucketElem
69    (
70        TElem* const                            value
71        , NameIdPoolBucketElem<TElem>* const    next
72    );
73    ~NameIdPoolBucketElem();
74
75    TElem*                          fData;
76    NameIdPoolBucketElem<TElem>*    fNext;
77private:
78    // -----------------------------------------------------------------------
79    //  Unimplemented constructors and operators
80    // -----------------------------------------------------------------------
81    NameIdPoolBucketElem(const NameIdPoolBucketElem<TElem>&);
82    NameIdPoolBucketElem<TElem>& operator=(const NameIdPoolBucketElem<TElem>&);
83};
84
85
86template <class TElem> class NameIdPool : public XMemory
87{
88public :
89    // -----------------------------------------------------------------------
90    //  Contructors and Destructor
91    // -----------------------------------------------------------------------
92    NameIdPool
93    (
94        const   unsigned int    hashModulus
95        , const unsigned int    initSize = 128
96        , MemoryManager* const  manager = XMLPlatformUtils::fgMemoryManager
97    );
98
99    ~NameIdPool();
100
101
102    // -----------------------------------------------------------------------
103    //  Element management
104    // -----------------------------------------------------------------------
105    bool containsKey(const XMLCh* const key) const;
106    void removeAll();
107
108
109    // -----------------------------------------------------------------------
110    //  Getters
111    // -----------------------------------------------------------------------
112    TElem* getByKey(const XMLCh* const key);
113    const TElem* getByKey(const XMLCh* const key) const;
114    TElem* getById(const unsigned elemId);
115    const TElem* getById(const unsigned elemId) const;
116
117    MemoryManager* getMemoryManager() const;
118    // -----------------------------------------------------------------------
119    //  Putters
120    //
121    //  Dups are not allowed and cause an IllegalArgumentException. The id
122    //  of the new element is returned.
123    // -----------------------------------------------------------------------
124    unsigned int put(TElem* const valueToAdopt);
125
126
127protected :
128    // -----------------------------------------------------------------------
129    //  Declare the enumerator our friend so he can see our members
130    // -----------------------------------------------------------------------
131    friend class NameIdPoolEnumerator<TElem>;
132
133
134private :
135    // -----------------------------------------------------------------------
136    //  Unused constructors and operators
137    // -----------------------------------------------------------------------
138    NameIdPool(const NameIdPool<TElem>&);
139    NameIdPool<TElem>& operator=(const NameIdPool<TElem>&);
140
141
142    // -----------------------------------------------------------------------
143    //  Private helper methods
144    // -----------------------------------------------------------------------
145    NameIdPoolBucketElem<TElem>* findBucketElem
146    (
147        const XMLCh* const      key
148        ,     unsigned int&     hashVal
149    );
150    const NameIdPoolBucketElem<TElem>* findBucketElem
151    (
152        const   XMLCh* const    key
153        ,       unsigned int&   hashVal
154    )   const;
155
156
157    // -----------------------------------------------------------------------
158    //  Data members
159    //
160    //  fBucketList
161    //      This is the array that contains the heads of all of the list
162    //      buckets, one for each possible hash value.
163    //
164    //  fIdPtrs
165    //  fIdPtrsCount
166    //      This is the array of pointers to the bucket elements in order of
167    //      their assigned ids. So taking id N and referencing this array
168    //      gives you the element with that id. The count field indicates
169    //      the current size of this list. When fIdCounter+1 reaches this
170    //      value the list must be expanded.
171    //
172    //  fIdCounter
173    //      This is used to give out unique ids to added elements. It starts
174    //      at zero (which means empty), and is bumped up for each newly added
175    //      element. So the first element is 1, the next is 2, etc... This
176    //      means that this value is set to the top index of the fIdPtrs array.
177    //
178    //  fHashModulus
179    //      This is the modulus to use in this pool. The fBucketList array
180    //      is of this size. It should be a prime number.
181    // -----------------------------------------------------------------------
182    MemoryManager*                  fMemoryManager;
183    NameIdPoolBucketElem<TElem>**   fBucketList;
184    TElem**                         fIdPtrs;
185    unsigned int                    fIdPtrsCount;
186    unsigned int                    fIdCounter;
187    unsigned int                    fHashModulus;
188};
189
190
191//
192//  An enumerator for a name id pool. It derives from the basic enumerator
193//  class, so that pools can be generically enumerated.
194//
195template <class TElem> class NameIdPoolEnumerator : public XMLEnumerator<TElem>, public XMemory
196{
197public :
198    // -----------------------------------------------------------------------
199    //  Constructors and Destructor
200    // -----------------------------------------------------------------------
201    NameIdPoolEnumerator
202    (
203                NameIdPool<TElem>* const    toEnum
204                , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager
205    );
206
207    NameIdPoolEnumerator
208    (
209        const   NameIdPoolEnumerator<TElem>& toCopy
210    );
211
212    virtual ~NameIdPoolEnumerator();
213
214    // -----------------------------------------------------------------------
215    //  Public operators
216    // -----------------------------------------------------------------------
217    NameIdPoolEnumerator<TElem>& operator=
218    (
219        const   NameIdPoolEnumerator<TElem>& toAssign
220    );
221   
222    // -----------------------------------------------------------------------
223    //  Enum interface
224    // -----------------------------------------------------------------------
225    bool hasMoreElements() const;
226    TElem& nextElement();
227    void Reset();
228    int  size()  const;
229
230private :
231    // -----------------------------------------------------------------------
232    //  Data Members
233    //
234    //  fCurIndex
235    //      This is the current index into the pool's id mapping array. This
236    //      is now we enumerate it.
237    //
238    //  fToEnum
239    //      The name id pool that is being enumerated.
240    // -----------------------------------------------------------------------
241    unsigned int            fCurIndex;
242    NameIdPool<TElem>*      fToEnum;
243    MemoryManager*          fMemoryManager;
244};
245
246XERCES_CPP_NAMESPACE_END
247
248#if !defined(XERCES_TMPLSINC)
249#include <xercesc/util/NameIdPool.c>
250#endif
251
252#endif
Note: See TracBrowser for help on using the repository browser.