ROOT logo
#include "hratree.h"
#include "hcategory.h"
#include "hlocation.h"
#include "hlocateddataobject.h"
#include "hiterator.h"
#include "hdebug.h"
#include "TIterator.h"
#include "TArrayI.h"
#include "TClass.h"

//*-- Author : Manuel Sanchez
//*-- Modified : 6/10/98 by Manuel Sanchez

//_HADES_CLASS_DESCRIPTION 
///////////////////////////////////////
//HRaTree, HRaNode, HRaIndexNode
//
// HRaTree stands for "Hades Random Access Tree". This class implements 
//random access to the objects in any category using a tree; the only condition
//is that the data objects in the category inherit from HLocatedDataObject, so
//the random access implemented by the HRaTree corresponds to the indexes 
//in the data objects rather than the natural indexing in the category.
//
// As said, the HRaTree is a tree of HRaNode objects. The lower level nodes
//are HRaIndexNode and store pointers to the actual data objects being accesed
//with the HRaTree.
////////////////////////////////////////

void HRaNode::clear(void) {
  //Calls "Clear" for each of the subnodes
  TIter next(fSubNodes);
  HRaNode *node;
  while ( (node=(HRaNode *)next())!=NULL) {
    node->clear();
  }
}

HRaNode::~HRaNode(void) {
    delete fSubNodes;
}

void HRaIndexNode::clear(void) {
  //Clears the pointers to the data objects being accessed throught the HRaTree
  fCells.Clear();
}

HRaTree::HRaTree(void) {
  //Constructor
 fRoot=NULL;
 fSourceCategory=NULL;
 fDepth=0;
 fLoc.setNIndex(0);
 fLowerLevel=0;
 fIter = NULL;
}

HRaTree::HRaTree(HCategory *cat,TArrayI *sizes) {
  //Constructor for a tree accesing the data in "cat". "sizes" gives the 
  //max size of each level in the tree.
  if (!cat->getClass()->InheritsFrom("HLocatedDataObject")) {
    Warning("HRaTree::HRaTree",
	    "Data class not inheriting from HlocatedDataObject");
    fSourceCategory=NULL;
    fDepth=0;
  } else {
    HLocatedDataObject *obj;
    fSourceCategory=cat;
    obj=(HLocatedDataObject *)cat->getClass()->New();
    fDepth=obj->getNLocationIndex();
    delete obj;
    fIter=(HIterator *)cat->MakeIterator();
  }
  buildTree(sizes);
  fLoc.setNIndex(0);
  fLowerLevel=0;
}

HRaTree::HRaTree(HCategory *cat,HLocation &loc,TArrayI *sizes) {
  //Constructor like the one before but accessing only those objects in the
  //category which correspond to the location "loc"
  if (!cat->getClass()->InheritsFrom("HLocatedDataObject")) {
    Warning("HRaTree::HRaTree",
	    "Data class not inheriting from HlocatedDataObject");
    fSourceCategory=NULL;
    fDepth=0;
  } else {
    HLocatedDataObject *obj;
    fSourceCategory=cat;
    obj=(HLocatedDataObject *)cat->getClass()->New();
    fDepth=obj->getNLocationIndex()-loc.getNIndex();
    delete obj;
    fIter=(HIterator *)cat->MakeIterator();
    fIter->gotoLocation(loc);
  }
  buildTree(sizes);
  fLoc=loc; // Cuidado con este...
  fLowerLevel=loc.getNIndex();
}

HRaNode *HRaTree::buildNode(TArrayI *sizes,Int_t lvl) {
  //Recursive function used to instantiate the tree.
  Int_t i;
  HRaNode *r=new HRaNode(sizes->At(lvl));
  if (sizes->GetSize()-2>lvl) {
    for (i=0;i<sizes->At(lvl);i++) {
      r->addSubNode(buildNode(sizes,lvl+1));
    }
  } else {
    for (i=0;i<sizes->At(lvl);i++) {
      r->addSubNode(new HRaIndexNode(sizes->At(lvl+1)));
    } 
  }
  return r;
}

Bool_t HRaTree::buildTree(TArrayI *sizes) {
  //Instantiates the tree using buildNode()
  Bool_t r=kTRUE;
  if (fDepth==sizes->GetSize()) {
    if (fDepth==1) {
      fRoot=new HRaIndexNode(sizes->At(0));
    } else {
      fRoot=buildNode(sizes,0);
    }
  } else {
    r=kFALSE;
    Error("buildTree","Sizes vector dimension and tree depth don't match");
  }
  return r;
}

HRaTree::~HRaTree(void) {
  //Destructor
  if (fRoot) delete fRoot;
  fSourceCategory=NULL;

  if(fIter) {
      delete fIter;
      fIter = NULL;
  }

}

Bool_t HRaTree::addObject(HLocatedDataObject *obj) {
  //Adds the pointer "obj" to the right place in the tree so it can be accesed
  //after.
  Int_t level=fLowerLevel;
  HRaNode *node=fRoot;
  HRaIndexNode *inode=NULL;
#if DEBUG_LEVEL>2
  gDebuger->enterFunc("HRaTree::addObject");
#endif

  if (fDepth==1) {
    inode=(HRaIndexNode *)fRoot;
  } else {
    for (level=fLowerLevel;level<fLowerLevel+fDepth-2;level++) { 
      //counts fDepth-2 times
      node=node->getSubNode(obj->getLocationIndex(level));
      if (node==NULL) return kFALSE;
    }

    inode=(HRaIndexNode *)node->getSubNode(obj->getLocationIndex(level));
    if (!node) return kFALSE;
  }
  level++;
#if DEBUG_LEVEL>2
  gDebuger->leaveFunc("HRaTree::addObject");
#endif
  inode->setCell(obj,obj->getLocationIndex(level));
  return kTRUE;
}

Bool_t HRaTree::update(void) {
  //Updates the contents of the tree with the data in the accessed category.
  HLocatedDataObject *obj;

  if (fDepth==0 || fRoot==NULL || fSourceCategory==NULL || fIter==NULL) {
    Error("update","Tree not properly constructed");
    return kFALSE;
  } else {
    fRoot->clear();
    fIter->gotoLocation(fLoc);
    while ( (obj=(HLocatedDataObject *)fIter->Next())!=NULL) {
      if (!addObject(obj)) {
	return kFALSE;
      }
    }
  }
  return kTRUE;
}

TObject *HRaTree::getObject(HLocation &aLoc) {
  //Returns the object corresponding to the location "loc"
  //Warning: for the sake of speed no index checking is done here.
  HRaNode *node=fRoot;
  Int_t level=0;

  //  if (!fRoot || aLoc.getNIndex()<fDepth) return NULL;
  for (level=0;level<fDepth-1;level++) {
    node=node->getSubNode(aLoc.getUncheckedIndex(level));
    if (!node) return NULL;
  }
  return ((HRaIndexNode *)node)->getCell(aLoc.getUncheckedIndex(level));
}

TObject *HRaTree::getObject(Int_t i1,Int_t i2,Int_t i3,Int_t i4,
					  Int_t i5,Int_t i6,Int_t i7,Int_t i8,
					  Int_t i9) {
  //Returns the object corresponding to the location with indexes:
  //"i1","i2" up to "i9"
  HRaNode *node=NULL;
  TObject *r=NULL;

  if (i1>-1 && fDepth>0) {
    node=fRoot;
    if(i2>-1 && fDepth>1) {
      node=node->getSubNode(i1);
      if (i3>-1&& fDepth>2) {
	node=node->getSubNode(i2);
	if (i4>-1&& fDepth>3) {
	  node=node->getSubNode(i3);
	  if (i5>-1&& fDepth>4) {
	    node=node->getSubNode(i4);
	    if (i6>-1&& fDepth>5) {
	      node=node->getSubNode(i5);
	      if (i7>-1&& fDepth>6) {
		node=node->getSubNode(i6);
		if (i8>-1&& fDepth>7) {
		  node=node->getSubNode(i7);
		  if (i9>-1&& fDepth>8) {
		    node=node->getSubNode(i8);
		    r=((HRaIndexNode *)node)->getCell(i9);
		  } else r=((HRaIndexNode *)node)->getCell(i8);
		} else r=((HRaIndexNode *)node)->getCell(i7);
	      } else r=((HRaIndexNode *)node)->getCell(i6);
	    } else r=((HRaIndexNode *)node)->getCell(i5);
	  } else r=((HRaIndexNode *)node)->getCell(i4);
	} else r=((HRaIndexNode *)node)->getCell(i3);
      } else r=((HRaIndexNode *)node)->getCell(i2);
    } else r=((HRaIndexNode *)node)->getCell(i1);
  } else r=NULL;
  return (r);
}

ClassImp(HRaNode)
ClassImp(HRaIndexNode)
ClassImp(HRaTree)
 hratree.cc:1
 hratree.cc:2
 hratree.cc:3
 hratree.cc:4
 hratree.cc:5
 hratree.cc:6
 hratree.cc:7
 hratree.cc:8
 hratree.cc:9
 hratree.cc:10
 hratree.cc:11
 hratree.cc:12
 hratree.cc:13
 hratree.cc:14
 hratree.cc:15
 hratree.cc:16
 hratree.cc:17
 hratree.cc:18
 hratree.cc:19
 hratree.cc:20
 hratree.cc:21
 hratree.cc:22
 hratree.cc:23
 hratree.cc:24
 hratree.cc:25
 hratree.cc:26
 hratree.cc:27
 hratree.cc:28
 hratree.cc:29
 hratree.cc:30
 hratree.cc:31
 hratree.cc:32
 hratree.cc:33
 hratree.cc:34
 hratree.cc:35
 hratree.cc:36
 hratree.cc:37
 hratree.cc:38
 hratree.cc:39
 hratree.cc:40
 hratree.cc:41
 hratree.cc:42
 hratree.cc:43
 hratree.cc:44
 hratree.cc:45
 hratree.cc:46
 hratree.cc:47
 hratree.cc:48
 hratree.cc:49
 hratree.cc:50
 hratree.cc:51
 hratree.cc:52
 hratree.cc:53
 hratree.cc:54
 hratree.cc:55
 hratree.cc:56
 hratree.cc:57
 hratree.cc:58
 hratree.cc:59
 hratree.cc:60
 hratree.cc:61
 hratree.cc:62
 hratree.cc:63
 hratree.cc:64
 hratree.cc:65
 hratree.cc:66
 hratree.cc:67
 hratree.cc:68
 hratree.cc:69
 hratree.cc:70
 hratree.cc:71
 hratree.cc:72
 hratree.cc:73
 hratree.cc:74
 hratree.cc:75
 hratree.cc:76
 hratree.cc:77
 hratree.cc:78
 hratree.cc:79
 hratree.cc:80
 hratree.cc:81
 hratree.cc:82
 hratree.cc:83
 hratree.cc:84
 hratree.cc:85
 hratree.cc:86
 hratree.cc:87
 hratree.cc:88
 hratree.cc:89
 hratree.cc:90
 hratree.cc:91
 hratree.cc:92
 hratree.cc:93
 hratree.cc:94
 hratree.cc:95
 hratree.cc:96
 hratree.cc:97
 hratree.cc:98
 hratree.cc:99
 hratree.cc:100
 hratree.cc:101
 hratree.cc:102
 hratree.cc:103
 hratree.cc:104
 hratree.cc:105
 hratree.cc:106
 hratree.cc:107
 hratree.cc:108
 hratree.cc:109
 hratree.cc:110
 hratree.cc:111
 hratree.cc:112
 hratree.cc:113
 hratree.cc:114
 hratree.cc:115
 hratree.cc:116
 hratree.cc:117
 hratree.cc:118
 hratree.cc:119
 hratree.cc:120
 hratree.cc:121
 hratree.cc:122
 hratree.cc:123
 hratree.cc:124
 hratree.cc:125
 hratree.cc:126
 hratree.cc:127
 hratree.cc:128
 hratree.cc:129
 hratree.cc:130
 hratree.cc:131
 hratree.cc:132
 hratree.cc:133
 hratree.cc:134
 hratree.cc:135
 hratree.cc:136
 hratree.cc:137
 hratree.cc:138
 hratree.cc:139
 hratree.cc:140
 hratree.cc:141
 hratree.cc:142
 hratree.cc:143
 hratree.cc:144
 hratree.cc:145
 hratree.cc:146
 hratree.cc:147
 hratree.cc:148
 hratree.cc:149
 hratree.cc:150
 hratree.cc:151
 hratree.cc:152
 hratree.cc:153
 hratree.cc:154
 hratree.cc:155
 hratree.cc:156
 hratree.cc:157
 hratree.cc:158
 hratree.cc:159
 hratree.cc:160
 hratree.cc:161
 hratree.cc:162
 hratree.cc:163
 hratree.cc:164
 hratree.cc:165
 hratree.cc:166
 hratree.cc:167
 hratree.cc:168
 hratree.cc:169
 hratree.cc:170
 hratree.cc:171
 hratree.cc:172
 hratree.cc:173
 hratree.cc:174
 hratree.cc:175
 hratree.cc:176
 hratree.cc:177
 hratree.cc:178
 hratree.cc:179
 hratree.cc:180
 hratree.cc:181
 hratree.cc:182
 hratree.cc:183
 hratree.cc:184
 hratree.cc:185
 hratree.cc:186
 hratree.cc:187
 hratree.cc:188
 hratree.cc:189
 hratree.cc:190
 hratree.cc:191
 hratree.cc:192
 hratree.cc:193
 hratree.cc:194
 hratree.cc:195
 hratree.cc:196
 hratree.cc:197
 hratree.cc:198
 hratree.cc:199
 hratree.cc:200
 hratree.cc:201
 hratree.cc:202
 hratree.cc:203
 hratree.cc:204
 hratree.cc:205
 hratree.cc:206
 hratree.cc:207
 hratree.cc:208
 hratree.cc:209
 hratree.cc:210
 hratree.cc:211
 hratree.cc:212
 hratree.cc:213
 hratree.cc:214
 hratree.cc:215
 hratree.cc:216
 hratree.cc:217
 hratree.cc:218
 hratree.cc:219
 hratree.cc:220
 hratree.cc:221
 hratree.cc:222
 hratree.cc:223
 hratree.cc:224
 hratree.cc:225
 hratree.cc:226
 hratree.cc:227
 hratree.cc:228
 hratree.cc:229
 hratree.cc:230
 hratree.cc:231
 hratree.cc:232
 hratree.cc:233
 hratree.cc:234
 hratree.cc:235
 hratree.cc:236
 hratree.cc:237
 hratree.cc:238
 hratree.cc:239
 hratree.cc:240
 hratree.cc:241
 hratree.cc:242
 hratree.cc:243
 hratree.cc:244
 hratree.cc:245
 hratree.cc:246
 hratree.cc:247
 hratree.cc:248