tcollex.cxx

Go to the documentation of this file.
00001 // @(#)root/test:$Id: tcollex.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Fons Rademakers   19/08/96
00003 
00004 #include <stdlib.h>
00005 
00006 #include "Riostream.h"
00007 #include "TString.h"
00008 #include "TObjString.h"
00009 #include "TSortedList.h"
00010 #include "TObjArray.h"
00011 #include "TOrdCollection.h"
00012 #include "THashTable.h"
00013 #include "TBtree.h"
00014 #include "TStopwatch.h"
00015 
00016 
00017 // To focus on basic collection protocol, this sample program uses
00018 // simple classes inheriting from TObject. One class, TObjString, is a
00019 // collectable string class (a TString wrapped in a TObject) provided
00020 // by the ROOT system. The other class we define below, is an integer
00021 // wrapped in a TObject, just like TObjString.
00022 
00023 
00024 // TObjNum is a simple container for an integer.
00025 class TObjNum : public TObject {
00026 private:
00027    int  num;
00028 
00029 public:
00030    TObjNum(int i = 0) : num(i) { }
00031    ~TObjNum() { Printf("~TObjNum = %d", num); }
00032    void    SetNum(int i) { num = i; }
00033    int     GetNum() { return num; }
00034    void    Print(Option_t *) const { Printf("TObjNum = %d", num); }
00035    ULong_t Hash() const { return num; }
00036    Bool_t  IsEqual(const TObject *obj) const { return num == ((TObjNum*)obj)->num; }
00037    Bool_t  IsSortable() const { return kTRUE; }
00038    Int_t   Compare(const TObject *obj) const { if (num > ((TObjNum*)obj)->num)
00039                                       return 1;
00040                                    else if (num < ((TObjNum*)obj)->num)
00041                                       return -1;
00042                                    else
00043                                       return 0; }
00044 };
00045 
00046 void Test_TObjArray()
00047 {
00048 
00049    Printf(
00050    "////////////////////////////////////////////////////////////////\n"
00051    "// Test of TObjArray                                          //\n"
00052    "////////////////////////////////////////////////////////////////"
00053    );
00054 
00055    // Array of capacity 10, Add() will automatically expand the array if necessary.
00056    TObjArray  a(10);
00057 
00058    Printf("Filling TObjArray");
00059    a.Add(new TObjNum(1));            // add at next free slot, pos 0
00060    a[1] = new TObjNum(2);            // use operator[], put at pos 1
00061    TObjNum *n3 = new TObjNum(3);
00062    a.AddAt(n3,2);                    // add at position 2
00063    a.Add(new TObjNum(4));            // add at next free slot, pos 3
00064    a.AddLast(new TObjNum(10));       // add at pos 4
00065    TObjNum n6(6);                    // stack based TObjNum
00066    a.AddAt(&n6,5);                   // add at pos 5
00067    a[6] = new TObjNum(5);            // add at respective positions
00068    a[7] = new TObjNum(8);
00069    a[8] = new TObjNum(7);
00070 //   a[10] = &n6;                    // gives out-of-bound error
00071 
00072    Printf("Print array");
00073    a.Print();                        // invoke Print() of all objects
00074 
00075    Printf("Sort array");
00076    a.Sort();
00077    for (int i = 0; i < a.Capacity(); i++)  // typical way of iterating over array
00078       if (a[i])
00079          a[i]->Print();      // can also use operator[] to access elements
00080       else
00081          Printf("%d empty slot", i);
00082 
00083    Printf("Use binary search to get position of number 6");
00084    Printf("6 is at position %d", a.BinarySearch(&n6));
00085 
00086    Printf("Find number before 6");
00087    a.Before(&n6)->Print();
00088 
00089    Printf("Find number after 3");
00090    a.After(n3)->Print();
00091 
00092    Printf("Remove 3 and print list again");
00093    a.Remove(n3);
00094    delete n3;
00095    a.Print();
00096 
00097    Printf("Iterate forward over list and remove 4 and 7");
00098 
00099    // TIter encapsulates the actual class iterator. The type of iterator
00100    // used depends on the type of the collection.
00101    TIter next(&a);
00102 
00103    TObjNum *obj;
00104    while ((obj = (TObjNum*)next()))     // iterator skips empty slots
00105       if (obj->GetNum() == 4) {
00106          a.Remove(obj);
00107          delete obj;
00108       }
00109 
00110    // Reset the iterator and loop again
00111    next.Reset();
00112    while ((obj = (TObjNum*)next()))
00113       if (obj->GetNum() == 7) {
00114          a.Remove(obj);
00115          delete obj;
00116       }
00117 
00118    Printf("Iterate backward over list and remove 2");
00119    TIter next1(&a, kIterBackward);
00120    while ((obj = (TObjNum*)next1()))
00121       if (obj->GetNum() == 2) {
00122          a.Remove(obj);
00123          delete obj;
00124       }
00125 
00126    Printf("Delete remainder of list: 1,5,8,10 (6 not deleted since not on heap)");
00127 
00128    // Delete heap objects and clear list. Attention: do this only when you
00129    // own all objects stored in the collection. When you stored aliases to
00130    // the actual objects (i.e. you did not create the objects) use Clear()
00131    // instead.
00132    a.Delete();
00133 
00134    Printf("Delete stack based objects (6)");
00135 }
00136 
00137 void Test_TOrdCollection()
00138 {
00139    Printf(
00140    "////////////////////////////////////////////////////////////////\n"
00141    "// Test of TOrdCollection                                     //\n"
00142    "////////////////////////////////////////////////////////////////"
00143    );
00144 
00145    // Create collection with default size, Add() will automatically expand
00146    // the collection if necessary.
00147    TOrdCollection  c;
00148 
00149    Printf("Filling TOrdCollection");
00150    c.Add(new TObjString("anton"));      // add at next free slot, pos 0
00151    c.AddFirst(new TObjString("bobo"));  // put at pos 0, bump anton to pos 1
00152    TObjString *s3 = new TObjString("damon");
00153    c.AddAt(s3,1);                       // add at position 1, bump anton to pos 2
00154    c.Add(new TObjString("cassius"));    // add at next free slot, pos 3
00155    c.AddLast(new TObjString("enigma")); // add at pos 4
00156    TObjString s6("fons");               // stack based TObjString
00157    c.AddBefore(s3,&s6);                 // add at pos 1
00158    c.AddAfter(s3, new TObjString("gaia"));
00159 
00160    Printf("Print collection");
00161    c.Print();                           // invoke Print() of all objects
00162 
00163    Printf("Sort collection");
00164    c.Sort();
00165    c.Print();
00166 
00167    Printf("Use binary search to get position of string damon");
00168    Printf("damon is at position %d", c.BinarySearch(s3));
00169 
00170    Printf("Find str before fons");
00171    c.Before(&s6)->Print();
00172 
00173    Printf("Find string after damon");
00174    c.After(s3)->Print();
00175 
00176    Printf("Remove damon and print list again");
00177    c.Remove(s3);
00178    delete s3;
00179    c.Print();
00180 
00181    Printf("Iterate forward over list and remove cassius");
00182    TObjString *objs;
00183    TIter next(&c);
00184    while ((objs = (TObjString*)next()))     // iterator skips empty slots
00185       if (objs->String() == "cassius") {
00186          c.Remove(objs);
00187          delete objs;
00188       }
00189 
00190    Printf("Iterate backward over list and remove gaia");
00191    TIter next1(&c, kIterBackward);
00192    while ((objs = (TObjString*)next1()))
00193       if (objs->String() == "gaia") {
00194          c.Remove(objs);
00195          delete objs;
00196       }
00197 
00198    Printf("Delete remainder of list: anton,bobo,enigma (fons not deleted since not on heap)");
00199    c.Delete();                        // delete heap objects and clear list
00200 
00201    Printf("Delete stack based objects (fons)");
00202 }
00203 
00204 void Test_TList()
00205 {
00206    Printf(
00207    "////////////////////////////////////////////////////////////////\n"
00208    "// Test of TList                                              //\n"
00209    "////////////////////////////////////////////////////////////////"
00210    );
00211 
00212    // Create a doubly linked list.
00213    TList l;
00214 
00215    Printf("Filling TList");
00216    TObjNum *n3 = new TObjNum(3);
00217    l.Add(n3);
00218    l.AddBefore(n3, new TObjNum(5));
00219    l.AddAfter(n3, new TObjNum(2));
00220    l.Add(new TObjNum(1));
00221    l.AddBefore(n3, new TObjNum(4));
00222    TObjNum n6(6);                     // stack based TObjNum
00223    l.AddFirst(&n6);
00224 
00225    Printf("Print list");
00226    l.Print();
00227 
00228    Printf("Remove 3 and print list again");
00229    l.Remove(n3);
00230    delete n3;
00231    l.Print();
00232 
00233    Printf("Iterate forward over list and remove 4");
00234    TObjNum *obj;
00235    TIter next(&l);
00236    while ((obj = (TObjNum*)next()))
00237       if (obj->GetNum() == 4) l.Remove(obj);
00238 
00239    Printf("Iterate backward over list and remove 2");
00240    TIter next1(&l, kIterBackward);
00241    while ((obj = (TObjNum*)next1()))
00242       if (obj->GetNum() == 2) {
00243          l.Remove(obj);
00244          delete obj;
00245       }
00246 
00247    Printf("Delete remainder of list: 1, 5 (6 not deleted since not on heap)");
00248    l.Delete();
00249 
00250    Printf("Delete stack based objects (6)");
00251 }
00252 
00253 void Test_TSortedList()
00254 {
00255    Printf(
00256    "////////////////////////////////////////////////////////////////\n"
00257    "// Test of TSortedList                                        //\n"
00258    "////////////////////////////////////////////////////////////////"
00259    );
00260 
00261    // Create a sorted doubly linked list.
00262    TSortedList sl;
00263 
00264    Printf("Filling TSortedList");
00265    TObjNum *n3 = new TObjNum(3);
00266    sl.Add(n3);
00267    sl.AddBefore(n3,new TObjNum(5));
00268    sl.AddAfter(n3, new TObjNum(2));
00269    sl.Add(new TObjNum(1));
00270    sl.AddBefore(n3, new TObjNum(4));
00271    TObjNum n6(6);                     // stack based TObjNum
00272    sl.AddFirst(&n6);
00273 
00274    Printf("Print list");
00275    sl.Print();
00276 
00277    Printf("Delete all heap based objects (6 not deleted since not on heap)");
00278    sl.Delete();
00279 
00280    Printf("Delete stack based objects (6)");
00281 }
00282 
00283 void Test_THashTable()
00284 {
00285    Printf(
00286    "////////////////////////////////////////////////////////////////\n"
00287    "// Test of THashTable                                         //\n"
00288    "////////////////////////////////////////////////////////////////"
00289    );
00290 
00291    int i;
00292 
00293    // Create a hash table with an initial size of 20 (actually the next prime
00294    // above 20). No automatic rehashing.
00295    THashTable ht(20);
00296 
00297    Printf("Filling THashTable");
00298    Printf("Number of slots before filling: %d", ht.Capacity());
00299    for (i = 0; i < 1000; i++)
00300       ht.Add(new TObject);
00301 
00302    Printf("Average collisions: %f", ht.AverageCollisions());
00303 
00304    // rehash the hash table to reduce the collission rate
00305    ht.Rehash(ht.GetSize());
00306 
00307    Printf("Number of slots after rehash: %d", ht.Capacity());
00308    Printf("Average collisions after rehash: %f", ht.AverageCollisions());
00309 
00310    ht.Delete();
00311 
00312    // Create a hash table and trigger automatic rehashing when average
00313    // collision rate becomes larger than 5.
00314    THashTable ht2(20,5);
00315 
00316    Printf("Filling THashTable with automatic rehash when AverageCollisions>5");
00317    Printf("Number of slots before filling: %d", ht2.Capacity());
00318    for (i = 0; i < 1000; i++)
00319       ht2.Add(new TObject);
00320 
00321    Printf("Number of slots after filling: %d", ht2.Capacity());
00322    Printf("Average collisions: %f", ht2.AverageCollisions());
00323 
00324    Printf("\nDelete all heap based objects");
00325    ht2.Delete();
00326 }
00327 
00328 void Test_TBtree()
00329 {
00330    Printf(
00331    "////////////////////////////////////////////////////////////////\n"
00332    "// Test of TBtree                                             //\n"
00333    "////////////////////////////////////////////////////////////////"
00334    );
00335    TStopwatch timer;      // create a timer
00336    TBtree     l;          // btree of order 3
00337 
00338    Printf("Filling TBtree");
00339 
00340    TObjNum *n3 = new TObjNum(3);
00341    l.Add(n3);
00342    l.AddBefore(n3,new TObjNum(5));
00343    l.AddAfter(n3, new TObjNum(2));
00344    l.Add(new TObjNum(1));
00345    l.AddBefore(n3, new TObjNum(4));
00346    TObjNum n6(6);                     // stack based TObjNum
00347    l.AddFirst(&n6);
00348 
00349    timer.Start();
00350    for (int i = 0; i < 50; i++)
00351       l.Add(new TObjNum(i));
00352    timer.Print();
00353 
00354    Printf("Print TBtree");
00355    l.Print();
00356 
00357    Printf("Remove 3 and print TBtree again");
00358    l.Remove(n3);
00359    l.Print();
00360 
00361    Printf("Iterate forward over TBtree and remove 4 from tree");
00362    TIter next(&l);
00363    TObjNum *obj;
00364    while ((obj = (TObjNum*)next()))
00365       if (obj->GetNum() == 4) l.Remove(obj);
00366 
00367    Printf("Iterate backward over TBtree and remove 2 from tree");
00368    TIter next1(&l, kIterBackward);
00369    while ((obj = (TObjNum*)next1()))
00370       if (obj->GetNum() == 2) l.Remove(obj);
00371 
00372    Printf("\nDelete all heap based objects");
00373    l.Delete();
00374 
00375    Printf("Delete stack based objects (6)");
00376 }
00377 
00378 
00379 int tcollex() {
00380    Test_TObjArray();
00381    Test_TOrdCollection();
00382    Test_TList();
00383    Test_TSortedList();
00384    Test_THashTable();
00385    Test_TBtree();
00386 
00387    return 0;
00388 }
00389 
00390 #ifndef __CINT__
00391 int main() {
00392    return tcollex();
00393 }
00394 #endif

Generated on Tue Jul 5 15:16:18 2011 for ROOT_528-00b_version by  doxygen 1.5.1