Warning, file /include/xercesc/util/ValueHashTableOf.c was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #if defined(XERCES_TMPLSINC)
0027 #include <xercesc/util/ValueHashTableOf.hpp>
0028 #endif
0029
0030 #include <xercesc/util/NullPointerException.hpp>
0031 #include <xercesc/util/Janitor.hpp>
0032 #include <assert.h>
0033 #include <new>
0034
0035 XERCES_CPP_NAMESPACE_BEGIN
0036
0037
0038
0039
0040 template <class TVal, class THasher>
0041 ValueHashTableOf<TVal, THasher>::ValueHashTableOf( const XMLSize_t modulus
0042 , const THasher& hasher
0043 , MemoryManager* const manager)
0044 : fMemoryManager(manager)
0045 , fBucketList(0)
0046 , fHashModulus(modulus)
0047 , fInitialModulus(modulus)
0048 , fCount(0)
0049 , fHasher(hasher)
0050 {
0051 initialize(modulus);
0052 }
0053
0054 template <class TVal, class THasher>
0055 ValueHashTableOf<TVal, THasher>::ValueHashTableOf( const XMLSize_t modulus
0056 , MemoryManager* const manager)
0057 : fMemoryManager(manager)
0058 , fBucketList(0)
0059 , fHashModulus(modulus)
0060 , fInitialModulus(modulus)
0061 , fCount(0)
0062 , fHasher()
0063 {
0064 initialize(modulus);
0065 }
0066
0067 template <class TVal, class THasher>
0068 void ValueHashTableOf<TVal, THasher>::initialize(const XMLSize_t modulus)
0069 {
0070 if (modulus == 0)
0071 ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::HshTbl_ZeroModulus, fMemoryManager);
0072
0073
0074 fBucketList = (ValueHashTableBucketElem<TVal>**) fMemoryManager->allocate
0075 (
0076 fHashModulus * sizeof(ValueHashTableBucketElem<TVal>*)
0077 );
0078 memset(fBucketList, 0, sizeof(fBucketList[0]) * fHashModulus);
0079 }
0080
0081 template <class TVal, class THasher>
0082 ValueHashTableOf<TVal, THasher>::~ValueHashTableOf()
0083 {
0084 removeAll();
0085
0086
0087 fMemoryManager->deallocate(fBucketList);
0088 }
0089
0090
0091
0092
0093
0094 template <class TVal, class THasher>
0095 bool ValueHashTableOf<TVal, THasher>::isEmpty() const
0096 {
0097 return fCount==0;
0098 }
0099
0100 template <class TVal, class THasher>
0101 bool ValueHashTableOf<TVal, THasher>::
0102 containsKey(const void* const key) const
0103 {
0104 XMLSize_t hashVal;
0105 const ValueHashTableBucketElem<TVal>* findIt = findBucketElem(key, hashVal);
0106 return (findIt != 0);
0107 }
0108
0109 template <class TVal, class THasher>
0110 void ValueHashTableOf<TVal, THasher>::
0111 removeKey(const void* const key)
0112 {
0113 XMLSize_t hashVal;
0114 removeBucketElem(key, hashVal);
0115 }
0116
0117 template <class TVal, class THasher>
0118 void ValueHashTableOf<TVal, THasher>::removeAll()
0119 {
0120 if(isEmpty())
0121 return;
0122
0123
0124 for (XMLSize_t buckInd = 0; buckInd < fHashModulus; buckInd++)
0125 {
0126
0127 ValueHashTableBucketElem<TVal>* curElem = fBucketList[buckInd];
0128 ValueHashTableBucketElem<TVal>* nextElem;
0129 while (curElem)
0130 {
0131
0132 nextElem = curElem->fNext;
0133
0134
0135
0136
0137 fMemoryManager->deallocate(curElem);
0138 curElem = nextElem;
0139 }
0140
0141
0142 fBucketList[buckInd] = 0;
0143 }
0144 fCount = 0;
0145 }
0146
0147
0148
0149
0150
0151 template <class TVal, class THasher>
0152 TVal& ValueHashTableOf<TVal, THasher>::get(const void* const key, MemoryManager* const manager)
0153 {
0154 XMLSize_t hashVal;
0155 ValueHashTableBucketElem<TVal>* findIt = findBucketElem(key, hashVal);
0156 if (!findIt)
0157 ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists, manager);
0158
0159 return findIt->fData;
0160 }
0161
0162 template <class TVal, class THasher>
0163 const TVal& ValueHashTableOf<TVal, THasher>::
0164 get(const void* const key) const
0165 {
0166 XMLSize_t hashVal;
0167 const ValueHashTableBucketElem<TVal>* findIt = findBucketElem(key, hashVal);
0168 if (!findIt)
0169 ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists, fMemoryManager);
0170
0171 return findIt->fData;
0172 }
0173
0174
0175
0176
0177
0178 template <class TVal, class THasher>
0179 void ValueHashTableOf<TVal, THasher>::put(void* key, const TVal& valueToAdopt)
0180 {
0181
0182 XMLSize_t threshold = fHashModulus * 3 / 4;
0183
0184
0185 if (fCount >= threshold)
0186 rehash();
0187
0188
0189 XMLSize_t hashVal;
0190 ValueHashTableBucketElem<TVal>* newBucket = findBucketElem(key, hashVal);
0191
0192
0193
0194
0195
0196 if (newBucket)
0197 {
0198 newBucket->fData = valueToAdopt;
0199 newBucket->fKey = key;
0200 }
0201 else
0202 {
0203 newBucket =
0204 new (fMemoryManager->allocate(sizeof(ValueHashTableBucketElem<TVal>)))
0205 ValueHashTableBucketElem<TVal>(key, valueToAdopt, fBucketList[hashVal]);
0206 fBucketList[hashVal] = newBucket;
0207 fCount++;
0208 }
0209 }
0210
0211
0212
0213
0214
0215
0216 template <class TVal, class THasher>
0217 void ValueHashTableOf<TVal, THasher>::rehash()
0218 {
0219 const XMLSize_t newMod = (fHashModulus * 2) + 1;
0220
0221 ValueHashTableBucketElem<TVal>** newBucketList =
0222 (ValueHashTableBucketElem<TVal>**) fMemoryManager->allocate
0223 (
0224 newMod * sizeof(ValueHashTableBucketElem<TVal>*)
0225 );
0226
0227
0228
0229 ArrayJanitor<ValueHashTableBucketElem<TVal>*> guard(newBucketList, fMemoryManager);
0230
0231 memset(newBucketList, 0, newMod * sizeof(newBucketList[0]));
0232
0233
0234
0235 for (XMLSize_t index = 0; index < fHashModulus; index++)
0236 {
0237
0238 ValueHashTableBucketElem<TVal>* curElem = fBucketList[index];
0239
0240 while (curElem)
0241 {
0242
0243 ValueHashTableBucketElem<TVal>* const nextElem = curElem->fNext;
0244
0245 const XMLSize_t hashVal = fHasher.getHashVal(curElem->fKey, newMod);
0246 assert(hashVal < newMod);
0247
0248 ValueHashTableBucketElem<TVal>* const newHeadElem = newBucketList[hashVal];
0249
0250
0251 curElem->fNext = newHeadElem;
0252 newBucketList[hashVal] = curElem;
0253
0254 curElem = nextElem;
0255 }
0256 }
0257
0258 ValueHashTableBucketElem<TVal>** const oldBucketList = fBucketList;
0259
0260
0261
0262 fBucketList = guard.release();
0263 fHashModulus = newMod;
0264
0265
0266 fMemoryManager->deallocate(oldBucketList);
0267
0268 }
0269
0270 template <class TVal, class THasher>
0271 inline ValueHashTableBucketElem<TVal>* ValueHashTableOf<TVal, THasher>::
0272 findBucketElem(const void* const key, XMLSize_t& hashVal)
0273 {
0274
0275 hashVal = fHasher.getHashVal(key, fHashModulus);
0276 assert(hashVal < fHashModulus);
0277
0278
0279 ValueHashTableBucketElem<TVal>* curElem = fBucketList[hashVal];
0280 while (curElem)
0281 {
0282 if (fHasher.equals(key, curElem->fKey))
0283 return curElem;
0284
0285 curElem = curElem->fNext;
0286 }
0287 return 0;
0288 }
0289
0290 template <class TVal, class THasher>
0291 inline const ValueHashTableBucketElem<TVal>* ValueHashTableOf<TVal, THasher>::
0292 findBucketElem(const void* const key, XMLSize_t& hashVal) const
0293 {
0294
0295 hashVal = fHasher.getHashVal(key, fHashModulus);
0296 assert(hashVal < fHashModulus);
0297
0298
0299 const ValueHashTableBucketElem<TVal>* curElem = fBucketList[hashVal];
0300 while (curElem)
0301 {
0302 if (fHasher.equals(key, curElem->fKey))
0303 return curElem;
0304
0305 curElem = curElem->fNext;
0306 }
0307 return 0;
0308 }
0309
0310
0311 template <class TVal, class THasher>
0312 void ValueHashTableOf<TVal, THasher>::
0313 removeBucketElem(const void* const key, XMLSize_t& hashVal)
0314 {
0315
0316 hashVal = fHasher.getHashVal(key, fHashModulus);
0317 assert(hashVal < fHashModulus);
0318
0319
0320
0321
0322
0323 ValueHashTableBucketElem<TVal>* curElem = fBucketList[hashVal];
0324 ValueHashTableBucketElem<TVal>* lastElem = 0;
0325
0326 while (curElem)
0327 {
0328 if (fHasher.equals(key, curElem->fKey))
0329 {
0330 if (!lastElem)
0331 {
0332
0333 fBucketList[hashVal] = curElem->fNext;
0334 }
0335 else
0336 {
0337
0338 lastElem->fNext = curElem->fNext;
0339 }
0340
0341
0342
0343
0344
0345 fMemoryManager->deallocate(curElem);
0346
0347 fCount--;
0348
0349 return;
0350 }
0351
0352
0353 lastElem = curElem;
0354 curElem = curElem->fNext;
0355 }
0356
0357
0358 ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::HshTbl_NoSuchKeyExists, fMemoryManager);
0359 }
0360
0361
0362
0363
0364
0365
0366
0367 template <class TVal, class THasher>
0368 ValueHashTableOfEnumerator<TVal, THasher>::
0369 ValueHashTableOfEnumerator(ValueHashTableOf<TVal, THasher>* const toEnum
0370 , const bool adopt
0371 , MemoryManager* const manager)
0372 : fAdopted(adopt), fCurElem(0), fCurHash((XMLSize_t)-1), fToEnum(toEnum), fMemoryManager(manager)
0373 {
0374 if (!toEnum)
0375 ThrowXMLwithMemMgr(NullPointerException, XMLExcepts::CPtr_PointerIsZero, manager);
0376
0377
0378
0379
0380
0381
0382
0383
0384 findNext();
0385 }
0386
0387 template <class TVal, class THasher>
0388 ValueHashTableOfEnumerator<TVal, THasher>::~ValueHashTableOfEnumerator()
0389 {
0390 if (fAdopted)
0391 delete fToEnum;
0392 }
0393
0394
0395
0396
0397
0398 template <class TVal, class THasher>
0399 bool ValueHashTableOfEnumerator<TVal, THasher>::hasMoreElements() const
0400 {
0401
0402
0403
0404
0405 if (!fCurElem && (fCurHash == fToEnum->fHashModulus))
0406 return false;
0407 return true;
0408 }
0409
0410 template <class TVal, class THasher>
0411 TVal& ValueHashTableOfEnumerator<TVal, THasher>::nextElement()
0412 {
0413
0414 if (!hasMoreElements())
0415 ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::Enum_NoMoreElements, fMemoryManager);
0416
0417
0418
0419
0420
0421 ValueHashTableBucketElem<TVal>* saveElem = fCurElem;
0422 findNext();
0423
0424 return saveElem->fData;
0425 }
0426
0427 template <class TVal, class THasher>
0428 void* ValueHashTableOfEnumerator<TVal, THasher>::nextElementKey()
0429 {
0430
0431 if (!hasMoreElements())
0432 ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::Enum_NoMoreElements, fMemoryManager);
0433
0434
0435
0436
0437
0438 ValueHashTableBucketElem<TVal>* saveElem = fCurElem;
0439 findNext();
0440
0441 return saveElem->fKey;
0442 }
0443
0444
0445 template <class TVal, class THasher>
0446 void ValueHashTableOfEnumerator<TVal, THasher>::Reset()
0447 {
0448 fCurHash = (XMLSize_t)-1;
0449 fCurElem = 0;
0450 findNext();
0451 }
0452
0453
0454
0455
0456
0457
0458 template <class TVal, class THasher>
0459 void ValueHashTableOfEnumerator<TVal, THasher>::findNext()
0460 {
0461
0462
0463
0464
0465 if (fCurElem)
0466 fCurElem = fCurElem->fNext;
0467
0468
0469
0470
0471
0472
0473 if (!fCurElem)
0474 {
0475 if (++fCurHash == fToEnum->fHashModulus)
0476 return;
0477
0478
0479 while (fToEnum->fBucketList[fCurHash]==0)
0480 {
0481
0482 if (++fCurHash == fToEnum->fHashModulus)
0483 return;
0484 }
0485 fCurElem = fToEnum->fBucketList[fCurHash];
0486 }
0487 }
0488
0489 XERCES_CPP_NAMESPACE_END