32 TExMap::TExMap(Int_t mapSize)
35 if (mapSize < 4) mapSize = 5;
39 case 5: fSize = 5;
break;
40 case 503: fSize = 503;
break;
42 fSize = (Int_t)TMath::NextPrime(mapSize);
44 fTable =
new Assoc_t [fSize];
46 memset(fTable,0,
sizeof(Assoc_t)*fSize);
53 TExMap::TExMap(
const TExMap &map) : TObject(map)
57 fTable =
new Assoc_t [fSize];
58 memcpy(fTable, map.fTable, fSize*
sizeof(Assoc_t));
64 TExMap& TExMap::operator=(
const TExMap &map)
67 TObject::operator=(map);
70 fTable =
new Assoc_t [fSize];
71 memcpy(fTable, map.fTable, fSize*
sizeof(Assoc_t));
81 delete [] fTable; fTable = 0;
87 void TExMap::Add(ULong64_t hash, Long64_t key, Long64_t value)
91 Int_t slot = FindElement(hash, key);
92 if (!fTable[slot].InUse()) {
93 fTable[slot].SetHash(hash);
94 fTable[slot].fKey = key;
95 fTable[slot].fValue = value;
100 Error(
"Add",
"key %lld is not unique", key);
116 void TExMap::AddAt(UInt_t slot, ULong64_t hash, Long64_t key, Long64_t value)
120 if (!fTable[slot].InUse()) {
121 fTable[slot].SetHash(hash);
122 fTable[slot].fKey = key;
123 fTable[slot].fValue = value;
138 Long64_t &TExMap::operator()(ULong64_t hash, Long64_t key)
142 Error(
"operator()",
"fTable==0, should never happen");
146 Int_t slot = FindElement(hash, key);
147 if (!fTable[slot].InUse()) {
148 fTable[slot].SetHash(hash);
149 fTable[slot].fKey = key;
150 fTable[slot].fValue = 0;
152 if (HighWaterMark()) {
154 slot = FindElement(hash, key);
157 return fTable[slot].fValue;
163 void TExMap::Delete(Option_t *)
165 memset(fTable,0,
sizeof(Assoc_t)*fSize);
173 Long64_t TExMap::GetValue(ULong64_t hash, Long64_t key)
175 if (!fTable)
return 0;
178 Int_t slot = Int_t(hash % fSize);
179 Int_t firstSlot = slot;
181 if (!fTable[slot].InUse())
return 0;
182 if (key == fTable[slot].fKey)
return fTable[slot].fValue;
183 if (++slot == fSize) slot = 0;
184 }
while (firstSlot != slot);
186 Error(
"GetValue",
"table full");
196 Long64_t TExMap::GetValue(ULong64_t hash, Long64_t key, UInt_t &slot)
198 if (!fTable) { slot = 0;
return 0; }
201 slot = Int_t(hash % fSize);
202 UInt_t firstSlot = slot;
204 if (!fTable[slot].InUse())
return 0;
205 if (key == fTable[slot].fKey)
return fTable[slot].fValue;
206 if (++slot == (UInt_t)fSize) slot = 0;
207 }
while (firstSlot != slot);
209 Error(
"GetValue",
"table full");
216 void TExMap::Remove(ULong64_t hash, Long64_t key)
221 Int_t i = FindElement(hash, key);
222 if (!fTable[i].InUse()) {
223 Error(
"Remove",
"key %lld not found at %d", key, i);
236 Int_t TExMap::FindElement(ULong64_t hash, Long64_t key)
238 if (!fTable)
return 0;
241 Int_t slot = Int_t(hash % fSize);
242 Int_t firstSlot = slot;
244 if (!fTable[slot].InUse())
return slot;
245 if (key == fTable[slot].fKey)
return slot;
246 if (++slot == fSize) slot = 0;
247 }
while (firstSlot != slot);
249 Error(
"FindElement",
"table full");
256 void TExMap::FixCollisions(Int_t index)
258 Int_t oldIndex, nextIndex;
261 for (oldIndex = index+1; ;oldIndex++) {
262 if (oldIndex >= fSize)
264 nextObject = fTable[oldIndex];
265 if (!nextObject.InUse())
267 nextIndex = FindElement(nextObject.GetHash(), nextObject.fKey);
268 if (nextIndex != oldIndex) {
269 fTable[nextIndex] = nextObject;
270 fTable[oldIndex].Clear();
278 void TExMap::Expand(Int_t newSize)
281 Assoc_t *oldTable = fTable;
282 Int_t oldsize = fSize;
283 newSize = (Int_t)TMath::NextPrime(newSize);
284 fTable =
new Assoc_t [newSize];
286 for (i = newSize; --i >= 0;) {
291 for (i = 0; i < oldsize; i++)
292 if (oldTable[i].InUse()) {
293 Int_t slot = FindElement(oldTable[i].GetHash(), oldTable[i].fKey);
294 if (!fTable[slot].InUse())
295 fTable[slot] = oldTable[i];
297 Error(
"Expand",
"slot %d not empty (should never happen)", slot);
305 void TExMap::Streamer(TBuffer &b)
311 Version_t R__v = b.ReadVersion(&R__s, &R__c);
312 TObject::Streamer(b);
323 for (i = 0; i < tally; ++i) {
328 Assoc_t *assoc = fTable + slot;
329 assoc->SetHash(hash);
331 assoc->fValue = value;
334 }
else if (R__v >= 2) {
343 for (i = 0; i < tally; ++i) {
348 Assoc_t* assoc = fTable + slot;
349 assoc->SetHash(hash);
351 assoc->fValue = value;
360 for (i = 0; i < n; i++) {
364 Add(hash, key, value);
367 b.CheckByteCount(R__s, R__c, TExMap::IsA());
369 R__c = b.WriteVersion(TExMap::IsA(), kTRUE);
371 TObject::Streamer(b);
375 for (i=0; i < fSize; i++) {
376 if (!fTable[i].InUse())
continue;
378 b << fTable[i].GetHash();
380 b << fTable[i].fValue;
382 b.SetByteCount(R__c, kTRUE);
387 ClassImp(TExMapIter);
392 TExMapIter::TExMapIter(
const TExMap *map) : fMap(map), fCursor(0)
399 TExMapIter &TExMapIter::operator=(
const TExMapIter &rhs)
403 fCursor = rhs.fCursor;
411 Bool_t TExMapIter::Next(ULong64_t &hash, Long64_t &key, Long64_t &value)
413 while (fCursor < fMap->fSize && !fMap->fTable[fCursor].InUse())
416 if (fCursor == fMap->fSize)
419 hash = fMap->fTable[fCursor].GetHash();
420 key = fMap->fTable[fCursor].fKey;
421 value = fMap->fTable[fCursor].fValue;
430 Bool_t TExMapIter::Next(Long64_t &key, Long64_t &value)
433 return Next(hash, key, value);