StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TDataSet.cxx
1 // @(#)root/table:$Id$
2 // Author: Valery Fine(fine@mail.cern.ch) 03/07/98
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "Riostream.h"
13 #include "TSystem.h"
14 #include "TDataSetIter.h"
15 #include "TDataSet.h"
16 
17 #include "TROOT.h"
18 #include "TBrowser.h"
19 
20 #include "TSystem.h"
21 #include <assert.h>
22 
24 // //
25 // TDataSet //
26 // //
27 // TDataSet class is to create a special compound object-container: //
28 // //
29 // ==================================================================== //
30 // TDataSet object ::= the "named" list of TDataSet objects //
31 // ==================================================================== //
32 // where the "list" (the pointer to TList object) may contain no object //
33 // //
34 // TDataSet object has a back pointer to its "parent" TDataSet //
35 // object, the "character" *name* and "character" *title* //
36 // //
37 // The service this class does provide is to help the user to build //
38 // and manage the hierarchy of their data but the data itself. //
39 // //
40 // So it is not "Container" itself rather the basement (base class) //
41 // to built the containers. //
42 // //
43 // One may derive the custom container classes from TDataSet. //
44 // See for example TObjectSet, TTable, TVolume, TFileSet //
45 // These classes derived from TDataSet: //
46 // //
47 // Class Name //
48 // ---------- //
49 // TObjectSet::public TDataSet - is a container for TObject //
50 // TTable:: public TDataSet - is a container for the array //
51 // of any "plain" C-structure //
52 // TNode:: public TDataSet - is a container for 3D objects //
53 // TMaker:: public TDataSet - is a container for STAR "control" //
54 // objects //
55 // etc etc //
56 // //
57 // TDataSet class is a base class to implement the directory-like //
58 // data structures and maintain it via TDataSetIter class iterator //
59 // //
60 // TDataSet can be iterated using an iterator object (see TDataSetIter) //
61 // or by TDataSet::Pass method (see below) //
62 // //
63 // Terms: Dataset - any object from the list above //
64 // ===== Member is called "DataSet Member" //
65 // //
66 // Structural - the "Dataset Member" is its //
67 // member "Structural member" if its "back pointer" //
68 // points to this object //
69 // //
70 // Dataset - we will say this TDataSet object "OWNs" //
71 // Owner (or is an OWNER / PARENT of ) another //
72 // (parent) TDataSet object if the last one is its //
73 // "Structural Member" //
74 // //
75 // Associated - If some object is not "Structural member" //
76 // member of this object we will say it is an //
77 // "Associated Member" of this dataset //
78 // //
79 // Orphan - If some dataset is a member of NO other //
80 // dataset TDataSet object it is called an "orphan" //
81 // dataset object //
82 // //
83 // - Any TDataSet object may be "Owned" by one and only one another //
84 // TDataSet object if any. //
85 // //
86 // - Any TDataSet object can be the "Structural Member" of one and //
87 // only one another TDataSet //
88 // //
89 // - Any TDataSet object may be an "Associated Member" for any number //
90 // of other TDataSet objects if any //
91 // //
92 // - NAME issue: //
93 // Each "dataset member" is in possession of some "alpha-numerical" //
94 // NAME as defined by TNamed class. //
95 // The NAME may contain any "printable" symbols but "SLASH" - "/" //
96 // The symbol "RIGHT SLASH" - "/" can not be used as any part of the //
97 // "DataSet Member" NAME //
98 // Any DataSet can be found by its NAME with TDataSetIter object //
99 // //
100 // - TITLE issue: //
101 // Each "dataset member" is in possession of the "alpha-numerical" //
102 // TITLE as defined by TNamed class. The meaning of the TITLE is //
103 // reserved for the derived classes to hold there some indetification //
104 // that is special for that derived class. //
105 // //
106 // This means the user must be careful about the "TDataSet //
107 // NAME and TITLE since this may cause some "side effects" of the //
108 // particular class functions //
109 // //
110 // - It is NOT required those all "DataSet Members" are in possession //
111 // of the unique names, i.e. any number of "DataSet Members" //
112 // may bear one and the same name //
113 // //
114 // Actions: //
115 // ======== //
116 // Create DataSet is born either as "Orphan" or //
117 // as "Structural Member" //
118 // of another TDataSet object //
119 // //
120 // Add One dataset can be included into another dataset. //
121 // Upon adding: //
122 // - the "Orphan dataset" becomes "Structural Member" //
123 // - "Structural Members" of another dataset becomes the //
124 // "Associated Member" of this datatset //
125 // //
126 // Delete - Upon deleting the "Structural Member": //
127 // - "REMOVES" itself from the "Parent DataSet". //
128 // - Its "Associated memberships" is not changed though //
129 // //
130 // The last means the DataSet with the "Associated Members"//
131 // may contain a DIED pointers to unexisting "Associated" //
132 // objects !!! //
133 // //
134 // Further information is provided my the particular method //
135 // descriptions. //
136 // //
137 // The TDataSet class has several methods to control object('s) //
138 // memberships //
139 // //
141 
142 TDataSet mainSet("DSMAIN");
143 TDataSet *TDataSet::fgMainSet = &mainSet;
144 
145 ClassImp(TDataSet);
146 
149 
150 TDataSet::TDataSet(const Char_t *name, TDataSet *parent, Bool_t arrayFlag)
151  : TNamed(name,"TDataSet"),fParent(0),fList(0)
152 {
153  if (name && strchr(name,'/')) {
154  Error("TDataSet::TDataSet","dataset name (%s) cannot contain a slash", name);
155  return;
156  }
157  fList =0; fParent=0;
158  if (arrayFlag) SetBit(kArray);
159  if (parent) parent->Add(this);
160 // else AddMain(this);
161 }
162 
165 
167 {
168  TDataSet *p = GetParent();
169  if (fgMainSet && p == fgMainSet) p = 0;
170  return p;
171 }
187 
188 TDataSet::TDataSet(const TDataSet &pattern,EDataSetPass iopt):TNamed(pattern.GetName(),pattern.GetTitle()),
189 fParent(0),fList(0)
190 {
191  TDataSet *set = 0;
192  TDataSetIter next((TDataSet *)&pattern);
193  Bool_t optsel = (iopt == kStruct);
194  Bool_t optall = (iopt == kAll);
195  while ((set = next())) {
196 // define the parent of the next set
197  TDataSet *parent = set->GetParent();
198  if ( optall || (optsel && parent == this) )
199  Add((TDataSet *)(set->Clone()));
200  }
201 }
202 
205 
206 TDataSet::TDataSet(TNode &)
207 {
208  assert(0);
209 }
212 
214 {
215  Shunt(0); Delete();
216 }
217 
220 
222 {
223  if (!fList)
224  fList = TestBit(kArray) ? (TSeqCollection *)new TObjArray : (TSeqCollection *) new TList;
225 }
226 
234 
235 void TDataSet::AddAt(TDataSet *dataset,Int_t idx)
236 {
237  if (!dataset) return;
238 
239  MakeCollection();
240 
241  // Check whether this new child has got any parent yet
242  if (!dataset->GetRealParent()) dataset->SetParent(this);
243  fList->AddAt(dataset,idx);
244 }
245 
253 
254 void TDataSet::AddAtAndExpand(TDataSet *dataset, Int_t idx)
255 {
256  if (!dataset) return;
257 
258  MakeCollection();
259 
260  // Check whether this new child has got any parent yet
261  if (!dataset->GetRealParent()) dataset->SetParent(this);
262  if (TestBit(kArray)) ((TObjArray *) fList)->AddAtAndExpand(dataset,idx);
263  else fList->AddAt(dataset,idx);
264 }
265 
268 
270 {
271  if (!dataset) return;
272 
273  MakeCollection();
274 
275  // Check whether this new child has got any parent yet
276  if (!dataset->GetRealParent()) dataset->SetParent(this);
277  fList->AddLast(dataset);
278 }
279 
282 
284 {
285  if (!dataset) return;
286 
287  MakeCollection();
288 
289  // Check whether this new child has got any partent yet
290  if (!dataset->GetRealParent()) dataset->SetParent(this);
291  fList->AddFirst(dataset);
292 }
293 
296 
297 void TDataSet::Browse(TBrowser *b)
298 {
299  TDataSetIter next(this);
300  TDataSet *obj;
301  if (b)
302  while ((obj = next())) b->Add(obj,obj->GetName());
303 }
304 
307 
308 TObject *TDataSet::Clone(const char*) const
309 {
310  return new TDataSet(*this);
311 }
312 
319 
320 void TDataSet::Delete(Option_t *opt)
321 {
322  if(opt){/*unused*/}
323 
324 // Delete list of the TDataSet
325  TSeqCollection *thisList = GetCollection();
326  if (!thisList) return;
327  fList = 0;
328  TIter next(thisList);
329  TDataSet *son = 0;
330  // Delete the "Structural Members" of this TDataSet only
331  while ((son = (TDataSet *)next())) {
332  if ( (!son->TObject::IsOnHeap()) || (this != son->TDataSet::GetParent()) ) continue;
333  // mark the object is deleted from the TDataSet dtor or Delete method
334  son->TDataSet::SetParent(0);
335  if (son->TDataSet::Last()) { son->TDataSet::Delete(); }
336  son->TObject::SetBit(kCanDelete);
337  delete son;
338  }
339  // Cleare list
340  thisList->Clear("nodelete");
341  delete thisList;
342 }
343 
346 
347 TDataSet *TDataSet::FindByPath(const Char_t *path) const
348 {
349  return Find(path);
350 }
351 
361 
362 TDataSet *TDataSet::Find(const Char_t *path) const
363 {
364  TDataSetIter next((TDataSet*)this);
365  return next.Find(path);
366 }
367 
377 
378 TDataSet *TDataSet::FindByName(const Char_t *name,const Char_t *path,Option_t *opt) const
379 {
380  TDataSetIter next((TDataSet*)this);
381  return next.FindByName(name,path,opt);
382 }
383 
393 
394 TDataSet *TDataSet::FindByTitle(const Char_t *title,const Char_t *path,Option_t *opt) const
395 {
396  TDataSetIter next((TDataSet*)this);
397  return next.FindByTitle(title,path,opt);
398 }
399 
402 
404 {
405  if (fList) return (TDataSet *)(fList->First());
406  return 0;
407 }
408 
411 
413 {
414  if (fgMainSet && set) fgMainSet->AddFirst(set);
415 }
416 
419 
421 {
422  return fgMainSet;
423 }
424 
427 
428 TObject *TDataSet::GetObject() const
429 {
430  Print("***DUMMY GetObject***\n");
431  return 0;
432 }
433 
436 
438 {
439  if (fList) return (TDataSet *)(fList->Last());
440  return 0;
441 }
442 
446 
448 {
449  TDataSet *set = 0;
450  TDataSet *parent = GetParent();
451  if (parent) {
452  TIter next(parent->GetCollection());
453  // Find this object
454  while ( (set = (TDataSet *)next()) && (set != this) ){}
455  if (set) set = (TDataSet *)next();
456  }
457  return set;
458 }
459 
463 
465 {
466  TDataSet *prev = 0;
467  TDataSet *set = 0;
468  TDataSet *parent = GetParent();
469  if (parent) {
470  TIter next(parent->GetCollection());
471  // Find this object
472  while ( (set = (TDataSet *)next()) && (set != this) ){prev = set;}
473  if (!set) prev = 0;
474  }
475  return prev;
476 }
479 
480 void TDataSet::SetObject(TObject * /*obj*/)
481 {
482  Print("***DUMMY PutObject***\n");
483 }
484 
494 
495 void TDataSet::ls(Option_t *option) const
496 {
497  if (option && !strcmp(option,"*")) ls(Int_t(0));
498  else {
499  TDataSet *set = 0;
500  if (option && strlen(option) > 0) {
501  TDataSetIter local((TDataSet*)this);
502  set = local(option);
503  } else
504  set = (TDataSet*)this;
505  if (set) set->ls(Int_t(1));
506  else
507  if (option) Warning("ls","Dataset <%s> not found",option);
508  }
509 }
510 
525 
526 void TDataSet::ls(Int_t depth) const
527 {
528  PrintContents();
529 
530  if (!fList || depth == 1 ) return;
531  if (!depth) depth = 99999;
532 
533  TIter next(fList);
534  TDataSet *d=0;
535  while ((d = (TDataSet *)next())) {
536  TROOT::IncreaseDirLevel();
537  d->ls(depth-1);
538  TROOT::DecreaseDirLevel();
539  }
540 }
545 
547 {
548  return instance();
549 }
550 
554 
555 Bool_t TDataSet::IsThisDir(const Char_t *dirname,int len,int ignorecase) const
556 {
557  if (!ignorecase) {
558  if (len<0) {return !strcmp (GetName(),dirname);
559  } else {return !strncmp(GetName(),dirname,len);}
560  } else {
561  const char *name = GetName();
562  if (len==-1) len = strlen(dirname);
563  for (int i=0;i<len;i++) { if ( tolower(name[i])!=tolower(dirname[i])) return 0;}
564  return 1;
565  }
566 }
567 
570 
572 {
573  Mark();
574  TDataSetIter nextMark(this,0);
575  TDataSet *set = 0;
576  while ( (set = nextMark()) ) set->Mark();
577 }
578 
581 
583 {
584  Mark(kMark,kReset);
585  TDataSetIter nextMark(this,0);
586  TDataSet *set = 0;
587  while ( (set = nextMark()) ) set->Mark(kMark,kReset);
588 }
589 
592 
594 {
595  if (IsMarked()) Mark(kMark,kReset);
596  else Mark();
597  TDataSetIter nextMark(this,0);
598  TDataSet *set = 0;
599  while (( set = nextMark()) ) {
600  if (set->IsMarked()) set->Mark(kMark,kReset);
601  else set->Mark();
602  }
603 }
604 
607 
608 Bool_t TDataSet::IsEmpty() const
609 {
610  return First() ? kFALSE : kTRUE ;
611 }
612 
617 
618 void TDataSet::PrintContents(Option_t *opt) const {
619  if (opt) { /* no used */ }
620  Printf("%3d - %s\t%s\n",TROOT::GetDirLevel(),(const char*)Path(),(char*)GetTitle());
621 }
622 
625 
626 TString TDataSet::Path() const
627 {
628  TString str;
629  TDataSet *parent = GetParent();
630  if (parent) {
631  str = parent->Path();
632  str += "/";
633  }
634  str += GetName();
635  return str;
636 }
637 
640 
642 {
643  if (fList && set) {
644  if (set->GetParent() == this) set->SetParent(0);
645  fList->Remove(set);
646  }
647 
648 }
649 
655 
657 {
658  TDataSet *set = 0;
659  if (fList) {
660  set = (TDataSet *)fList->At(idx);
661  fList->RemoveAt(idx);
662  if (set && (set->GetParent() == this) ) set->SetParent(0);
663  }
664  return set;
665 }
666 
688 
689 TDataSet::EDataSetPass TDataSet::Pass(EDataSetPass ( *callback)(TDataSet *),Int_t depth)
690 {
691  if (!callback) return kStop;
692 
693  EDataSetPass condition = callback(this);
694 
695  if (condition == kContinue){
696  if (fList && depth != 1 ) {
697  TIter next(fList);
698  TDataSet *d=0;
699  while ( (d = (TDataSet *)next()) ) {
700  condition = d->Pass(callback, depth == 0 ? 0 : --depth);
701  if (condition == kStop || condition == kUp) break;
702  }
703  }
704  }
705  return condition==kUp ? kContinue:condition;
706 }
707 
729 
730 TDataSet::EDataSetPass TDataSet::Pass(EDataSetPass ( *callback)(TDataSet *,void*),void *user,Int_t depth)
731 {
732  if (!callback) return kStop;
733 
734  EDataSetPass condition = callback(this,user);
735 
736  if (condition == kContinue){
737  if (fList && depth != 1 ) {
738  TIter next(fList);
739  TDataSet *d=0;
740  while ((d = (TDataSet *)next())) {
741  condition = d->Pass(callback, user, depth == 0 ? 0 : --depth);
742  if (condition == kStop) break;
743  if (condition == kUp ) break;
744  }
745  }
746  }
747  return (condition==kUp) ? kContinue:condition;
748 }
749 
757 
758 Int_t TDataSet::Purge(Option_t *)
759 {
760  if (!fList) return 0;
761  TIter next(fList);
762  TDataSet *son = 0;
763  // Purge "Structural Members" only
764  TList garbage;
765  while ((son = (TDataSet *)next())) {
766  if (this == son->GetParent()) continue;
767  // mark the object is deleted from the TDataSet dtor
768  son->Purge();
769  if (son->HasData() || son->GetListSize()) continue;
770  delete son;
771  }
772  return 0;
773 }
774 
783 
785 {
786  fParent = parent;
787 }
788 
796 
798 {
799  Write();
800 }
801 
809 
810 void TDataSet::Shunt(TDataSet *newParent)
811 {
812  if (fParent) fParent->Remove(this);
813  if (newParent) newParent->Add(this);
814 }
815 
824 
825 void TDataSet::Update(TDataSet* set,UInt_t opt)
826 {
827  if(opt){/*unused*/}
828  if(!set) return;
829 
830  SetTitle(set->GetTitle());
831  TDataSetIter nextnew(set);
832  TDataSet *newset = 0;
833  while((newset = nextnew())) {
834  Bool_t found = kFALSE;
835  // Check whether this has the list of the sons
836  if (fList) {
837  TIter nextold(fList);
838  const Char_t *newname = newset->GetName();
839  TDataSet *oldset = 0;
840  while ( ((oldset = (TDataSet *)nextold())!=0) && !found) {
841  // if the "new" set does contain the dataset
842  // with the same name as ours update it too
843  // (We do not update itself (oldset == newset)
844  if ( (oldset != newset) && oldset->IsThisDir(newname) ) {
845  oldset->Update(newset);
846  found = kTRUE;
847  }
848  }
849  }
850  // If the new "set" contains some new dataset with brand-new name
851  // move it into the our dataset and remove it from its old location
852  if (!found) newset->Shunt(this);
853  }
854 }
855 
863 
865 {
866  TDataSetIter next(this);
867  TDataSet *set = 0;
868  while(( set = next())) set->Update();
869 }
870 
873 
875 {
876  TDataSetIter next(this,0);
877  TDataSet *ds;
878  TList *list;
879  while ((ds=next())) {
880  list = ds->GetList();
881  if (!list) continue;
882  list->Sort(); ds->Sort();
883  }
884 }
885 
892 
893 Int_t TDataSet::Write(const char *name, Int_t option, Int_t bufsize)
894 {
895  TDataSet *saveParent = fParent; // GetParent();
896  fParent = 0;
897  Int_t nbytes = TObject::Write(name,option, bufsize);
898  fParent = saveParent;
899  return nbytes;
900 }
901 
908 
909 Int_t TDataSet::Write(const char *name, Int_t option, Int_t bufsize) const
910 {
911  TDataSet *saveParent = fParent; // GetParent();
912  const_cast<TDataSet*>(this)->fParent = 0;
913  Int_t nbytes = TObject::Write(name,option, bufsize);
914  const_cast<TDataSet*>(this)->fParent = saveParent;
915  return nbytes;
916 }
virtual Bool_t IsThisDir(const char *dirname, int len=-1, int ignorecase=0) const
Definition: TDataSet.cxx:555
virtual TDataSet * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TDataSet.cxx:403
void MarkAll()
Mark all members of this dataset.
Definition: TDataSet.cxx:571
Definition: FJcore.h:367
virtual TDataSet * FindByTitle(const Char_t *title, const Char_t *path="", Option_t *opt="")
to be documented
static TDataSet * GetMainSet()
return pointer to the main dataset
Definition: TDataSet.cxx:420
virtual TDataSet * Instance() const
Definition: TDataSet.cxx:546
virtual TDataSet * FindByTitle(const char *title, const char *path="", Option_t *opt="") const
Definition: TDataSet.cxx:394
virtual TDataSet * FindByPath(const char *path) const
Aliase for TDataSet::Find(const Char_t *path) method.
Definition: TDataSet.cxx:347
virtual EDataSetPass Pass(EDataSetPass(*callback)(TDataSet *), Int_t depth=0)
Definition: TDataSet.cxx:689
virtual void PrintContents(Option_t *opt="") const
Definition: TDataSet.cxx:618
virtual void AddAtAndExpand(TDataSet *dataset, Int_t idx=0)
Definition: TDataSet.cxx:254
virtual void Delete(Option_t *opt="")
Definition: TDataSet.cxx:320
virtual void Remove(TDataSet *set)
Remiove the &quot;set&quot; from this TDataSet.
Definition: TDataSet.cxx:641
virtual TDataSet * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TDataSet.cxx:437
TDataSet * GetRealParent()
return real parent
Definition: TDataSet.cxx:166
virtual void Browse(TBrowser *b)
Browse this dataset (called by TBrowser).
Definition: TDataSet.cxx:297
virtual void SetObject(TObject *obj)
The depricated method (left here for the sake of the backward compatibility)
Definition: TDataSet.cxx:480
virtual TObject * Clone(const char *newname="") const
the custom implementation fo the TObject::Clone
Definition: TDataSet.cxx:308
void InvertAllMarks()
Invert mark bit for all members of this dataset.
Definition: TDataSet.cxx:593
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Definition: TDataSet.cxx:893
virtual TDataSet * Prev() const
Definition: TDataSet.cxx:464
virtual void SetWrite()
Definition: TDataSet.cxx:797
virtual void ls(Option_t *option="") const
Definition: TDataSet.cxx:495
virtual void AddLast(TDataSet *dataset)
Add TDataSet object at the end of the dataset list of this dataset.
Definition: TDataSet.cxx:269
virtual TDataSet * FindByName(const Char_t *name, const Char_t *path="", Option_t *opt="")
to be documented
virtual Bool_t IsEmpty() const
return kTRUE if the &quot;internal&quot; collection has no member
Definition: TDataSet.cxx:608
virtual TDataSet * Next() const
Definition: TDataSet.cxx:447
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TDataSet.cxx:428
virtual ~TDataSet()
std::cout &lt;&lt; &quot;Default destructor for &quot; &lt;&lt; GetName() &lt;&lt; &quot; - &quot; &lt;&lt; GetTitle() &lt;&lt; std::endl; ...
Definition: TDataSet.cxx:213
virtual void AddFirst(TDataSet *dataset)
Add TDataSet object at the beginning of the dataset list of this dataset.
Definition: TDataSet.cxx:283
virtual void AddAt(TDataSet *dataset, Int_t idx=0)
Definition: TDataSet.cxx:235
virtual Int_t Purge(Option_t *opt="")
Definition: TDataSet.cxx:758
virtual void Shunt(TDataSet *newParent=0)
Definition: TDataSet.cxx:810
virtual void Sort()
Sort recursively all members of the TDataSet with TList::Sort method.
Definition: TDataSet.cxx:874
virtual TDataSet * FindByName(const char *name, const char *path="", Option_t *opt="") const
Definition: TDataSet.cxx:378
virtual void SetParent(TDataSet *parent=0)
Definition: TDataSet.cxx:784
virtual void Update()
Definition: TDataSet.cxx:864
virtual TDataSet * Find(const Char_t *path, TDataSet *rootset=0, Bool_t mkdir=kFALSE, Bool_t titleFlag=kFALSE)
virtual TString Path() const
return the full path of this data set
Definition: TDataSet.cxx:626
void UnMarkAll()
UnMark all members of this dataset.
Definition: TDataSet.cxx:582
void AddMain(TDataSet *set)
add data set to main data set
Definition: TDataSet.cxx:412
void MakeCollection()
Create the internal container at once if any.
Definition: TDataSet.cxx:221
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362
virtual TDataSet * RemoveAt(Int_t idx)
Definition: TDataSet.cxx:656