00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "TMap.h"
00031 #include "THashTable.h"
00032 #include "TROOT.h"
00033 #include "TBrowser.h"
00034 #include "TRegexp.h"
00035
00036 ClassImp(TMap)
00037
00038
00039 TMap::TMap(Int_t capacity, Int_t rehashlevel)
00040 {
00041
00042
00043 fSize = 0;
00044 fTable = new THashTable(capacity, rehashlevel);
00045 }
00046
00047
00048 TMap::~TMap()
00049 {
00050
00051
00052
00053 Clear();
00054 delete fTable;
00055 }
00056
00057
00058 void TMap::Add(TObject *)
00059 {
00060
00061
00062
00063 MayNotUse("Add(TObject *obj)");
00064 }
00065
00066
00067 void TMap::Add(TObject *key, TObject *value)
00068 {
00069
00070
00071 if (IsArgNull("Add", key)) return;
00072
00073 fTable->Add(new TPair(key, value));
00074 fSize++;
00075 }
00076
00077
00078 Float_t TMap::AverageCollisions() const
00079 {
00080
00081
00082 return fTable->AverageCollisions();
00083 }
00084
00085
00086 Int_t TMap::Capacity() const
00087 {
00088
00089
00090
00091 return fTable->Capacity();
00092 }
00093
00094
00095 void TMap::Clear(Option_t *option)
00096 {
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 if (IsOwner() && IsOwnerValue())
00107 DeleteAll();
00108 else if (IsOwner())
00109 Delete();
00110 else if (IsOwnerValue())
00111 DeleteValues();
00112 else {
00113 fTable->Delete(option);
00114 fSize = 0;
00115 }
00116 }
00117
00118
00119 Int_t TMap::Collisions(const char *keyname) const
00120 {
00121
00122
00123
00124
00125 return fTable->Collisions(keyname);
00126 }
00127
00128
00129 Int_t TMap::Collisions(TObject *key) const
00130 {
00131
00132
00133
00134 return fTable->Collisions(key);
00135 }
00136
00137
00138 void TMap::Delete(Option_t *option)
00139 {
00140
00141
00142
00143 TIter next(fTable);
00144 TPair *a;
00145
00146 while ((a = (TPair *)next()))
00147 if (a->Key() && a->Key()->IsOnHeap())
00148 TCollection::GarbageCollect(a->Key());
00149
00150 fTable->Delete(option);
00151 fSize = 0;
00152 }
00153
00154
00155 void TMap::DeleteValues()
00156 {
00157
00158
00159
00160 TIter next(fTable);
00161 TPair *a;
00162
00163 while ((a = (TPair *)next()))
00164 if (a->Value() && a->Value()->IsOnHeap())
00165 TCollection::GarbageCollect(a->Value());
00166
00167 fTable->Delete();
00168 fSize = 0;
00169 }
00170
00171
00172 void TMap::DeleteAll()
00173 {
00174
00175
00176
00177 TIter next(fTable);
00178 TPair *a;
00179
00180 while ((a = (TPair *)next())) {
00181 if (a->Key() && a->Key()->IsOnHeap())
00182 TCollection::GarbageCollect(a->Key());
00183 if (a->Value() && a->Value()->IsOnHeap())
00184 TCollection::GarbageCollect(a->Value());
00185 }
00186
00187 fTable->Delete();
00188 fSize = 0;
00189 }
00190
00191
00192 Bool_t TMap::DeleteEntry(TObject *key)
00193 {
00194
00195
00196
00197
00198
00199 if (!key) return kFALSE;
00200
00201 TPair *a;
00202 if ((a = (TPair *)fTable->FindObject(key))) {
00203 if (fTable->Remove(key)) {
00204 if (IsOwner() && a->Key() && a->Key()->IsOnHeap())
00205 TCollection::GarbageCollect(a->Key());
00206 if (IsOwnerValue() && a->Value() && a->Value()->IsOnHeap())
00207 TCollection::GarbageCollect(a->Value());
00208 delete a;
00209 fSize--;
00210 return kTRUE;
00211 }
00212 }
00213 return kFALSE;
00214 }
00215
00216
00217 TObject *TMap::FindObject(const char *keyname) const
00218 {
00219
00220
00221
00222
00223
00224 return fTable->FindObject(keyname);
00225 }
00226
00227
00228 TObject *TMap::FindObject(const TObject *key) const
00229 {
00230
00231
00232
00233
00234
00235 if (IsArgNull("FindObject", key)) return 0;
00236
00237 return fTable->FindObject(key);
00238 }
00239
00240
00241 TObject *TMap::GetValue(const char *keyname) const
00242 {
00243
00244
00245 TPair *a = (TPair *)fTable->FindObject(keyname);
00246 if (a) return a->Value();
00247 return 0;
00248 }
00249
00250
00251 TObject *TMap::GetValue(const TObject *key) const
00252 {
00253
00254
00255 if (IsArgNull("GetValue", key)) return 0;
00256
00257 TPair *a = (TPair *)fTable->FindObject(key);
00258 if (a) return a->Value();
00259 return 0;
00260 }
00261
00262
00263 TIterator *TMap::MakeIterator(Bool_t dir) const
00264 {
00265
00266
00267 return new TMapIter(this, dir);
00268 }
00269
00270
00271 void TMap::PrintCollectionEntry(TObject* entry, Option_t* option, Int_t recurse) const
00272 {
00273
00274
00275 TObject* val = GetValue(entry);
00276
00277 TROOT::IndentLevel();
00278 printf("Key: ");
00279 entry->Print();
00280 TROOT::IndentLevel();
00281 if (TStorage::IsOnHeap(val)) {
00282 printf("Value: ");
00283 TCollection* coll = dynamic_cast<TCollection*>(val);
00284 if (coll) {
00285 coll->Print(option, recurse);
00286 } else {
00287 val->Print(option);
00288 }
00289 } else {
00290 printf("Value: 0x%lx\n", (ULong_t) val);
00291 }
00292 }
00293
00294
00295 void TMap::Rehash(Int_t newCapacity, Bool_t checkObjValidity)
00296 {
00297
00298
00299 fTable->Rehash(newCapacity, checkObjValidity);
00300 }
00301
00302
00303 TObject *TMap::Remove(TObject *key)
00304 {
00305
00306
00307
00308
00309 if (!key) return 0;
00310
00311 TPair *a;
00312 if ((a = (TPair *)fTable->FindObject(key))) {
00313 if (fTable->Remove(key)) {
00314 if (IsOwnerValue() && a->Value() && a->Value()->IsOnHeap())
00315 TCollection::GarbageCollect(a->Value());
00316 TObject *kobj = a->Key();
00317 delete a;
00318 fSize--;
00319 return kobj;
00320 }
00321 }
00322 return 0;
00323 }
00324
00325
00326 TPair *TMap::RemoveEntry(TObject *key)
00327 {
00328
00329
00330
00331
00332
00333 if (!key) return 0;
00334
00335 TPair *a;
00336 if ((a = (TPair *)fTable->FindObject(key))) {
00337 if (fTable->Remove(key)) {
00338 fSize--;
00339 return a;
00340 }
00341 }
00342 return 0;
00343 }
00344
00345
00346 void TMap::SetOwnerValue(Bool_t enable)
00347 {
00348
00349
00350
00351
00352
00353
00354 if (enable)
00355 SetBit(kIsOwnerValue);
00356 else
00357 ResetBit(kIsOwnerValue);
00358 }
00359
00360
00361 void TMap::SetOwnerKeyValue(Bool_t ownkeys, Bool_t ownvals)
00362 {
00363
00364
00365 SetOwner(ownkeys);
00366 SetOwnerValue(ownvals);
00367 }
00368
00369
00370 void TMap::Streamer(TBuffer &b)
00371 {
00372
00373
00374 TObject *obj=0;
00375 UInt_t R__s, R__c;
00376
00377 if (b.IsReading()) {
00378 Int_t nobjects;
00379 TObject *value=0;
00380
00381 Version_t v = b.ReadVersion(&R__s, &R__c);
00382 if (v > 2)
00383 TObject::Streamer(b);
00384 if (v > 1)
00385 fName.Streamer(b);
00386 b >> nobjects;
00387 for (Int_t i = 0; i < nobjects; i++) {
00388 b >> obj;
00389 b >> value;
00390 if (obj) Add(obj, value);
00391 }
00392 b.CheckByteCount(R__s, R__c,TMap::IsA());
00393 } else {
00394 R__c = b.WriteVersion(TMap::IsA(), kTRUE);
00395 TObject::Streamer(b);
00396 fName.Streamer(b);
00397 b << GetSize();
00398 TIter next(fTable);
00399 TPair *a;
00400 while ((a = (TPair*) next())) {
00401 b << a->Key();
00402 b << a->Value();
00403 }
00404 b.SetByteCount(R__c, kTRUE);
00405 }
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415 void TPair::Browse(TBrowser *b)
00416 {
00417
00418
00419 if (b) {
00420 if (fKey) b->Add(fKey);
00421 if (fValue) b->Add(fValue);
00422 } else {
00423 if (fKey) fKey->Browse(b);
00424 if (fValue) fValue->Browse(b);
00425 }
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 ClassImp(TMapIter)
00437
00438
00439 TMapIter::TMapIter(const TMap *m, Bool_t dir)
00440 {
00441
00442
00443 fMap = m;
00444 fDirection = dir;
00445 fCursor = 0;
00446 }
00447
00448
00449 TMapIter::TMapIter(const TMapIter &iter) : TIterator(iter)
00450 {
00451
00452
00453 fMap = iter.fMap;
00454 fDirection = iter.fDirection;
00455 fCursor = 0;
00456 if (iter.fCursor) {
00457 fCursor = (THashTableIter *)iter.fCursor->GetCollection()->MakeIterator();
00458 fCursor->operator=(*iter.fCursor);
00459 }
00460 }
00461
00462
00463 TIterator &TMapIter::operator=(const TIterator &rhs)
00464 {
00465
00466
00467 if (this != &rhs && rhs.IsA() == TMapIter::Class()) {
00468 const TMapIter &rhs1 = (const TMapIter &)rhs;
00469 fMap = rhs1.fMap;
00470 fDirection = rhs1.fDirection;
00471 if (rhs1.fCursor) {
00472 fCursor = (THashTableIter *)rhs1.fCursor->GetCollection()->MakeIterator();
00473 fCursor->operator=(*rhs1.fCursor);
00474 }
00475 }
00476 return *this;
00477 }
00478
00479
00480 TMapIter &TMapIter::operator=(const TMapIter &rhs)
00481 {
00482
00483
00484 if (this != &rhs) {
00485 fMap = rhs.fMap;
00486 fDirection = rhs.fDirection;
00487 if (rhs.fCursor) {
00488 fCursor = (THashTableIter *)rhs.fCursor->GetCollection()->MakeIterator();
00489 fCursor->operator=(*rhs.fCursor);
00490 }
00491 }
00492 return *this;
00493 }
00494
00495
00496 TMapIter::~TMapIter()
00497 {
00498
00499
00500 Reset();
00501 }
00502
00503
00504 TObject *TMapIter::Next()
00505 {
00506
00507
00508
00509 if (!fCursor)
00510 fCursor = new THashTableIter(fMap->fTable, fDirection);
00511
00512 TPair *a = (TPair *)fCursor->Next();
00513 if (a) return a->Key();
00514 return 0;
00515 }
00516
00517
00518 void TMapIter::Reset()
00519 {
00520
00521
00522 SafeDelete(fCursor);
00523 }
00524
00525
00526 bool TMapIter::operator!=(const TIterator &aIter) const
00527 {
00528
00529
00530 if (nullptr == (&aIter))
00531 return fCursor->operator*();
00532
00533 if (aIter.IsA() == TMapIter::Class()) {
00534 const TMapIter &iter(dynamic_cast<const TMapIter &>(aIter));
00535 return (fCursor->operator*() != iter.fCursor->operator*());
00536 }
00537 return false;
00538 }
00539
00540
00541 bool TMapIter::operator!=(const TMapIter &aIter) const
00542 {
00543
00544
00545 if (nullptr == (&aIter))
00546 return fCursor->operator*();
00547
00548 return (fCursor->operator*() != aIter.fCursor->operator*());
00549 }
00550
00551
00552 TObject *TMapIter::operator*() const
00553 {
00554
00555
00556 return (fCursor ? fCursor->operator*() : nullptr);
00557 }