ROOT logo
/**************************************************************************
 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliRefArray.h"
#include <string.h>

ClassImp(AliRefArray)

//____________________________________________________________________
AliRefArray::AliRefArray() : fNElems(0),fRefSize(0),fElems(0),fRefInd(0),fRefBuff(0)
{
  // default constructor
}
 
//____________________________________________________________________
AliRefArray::AliRefArray(UInt_t nelem,UInt_t depth) : 
  TObject(),fNElems(nelem),fRefSize(depth),fElems(0),fRefInd(0),fRefBuff(0)
{
  // constructor
  fNElems = nelem;
  // create array with nelem initial referres
  if (fNElems<1) fNElems = 1;
  fElems   = new Int_t[fNElems];   
  if (fRefSize>0) {
    fRefInd  = new UInt_t[fRefSize];  
    fRefBuff = new UInt_t[fRefSize];  
  }
  Reset();
  //
}
 
//____________________________________________________________________
AliRefArray::AliRefArray(const AliRefArray& src) :
  TObject(src),
  fNElems(src.fNElems),
  fRefSize(src.fRefSize),
  fElems(new Int_t[fNElems]),
  fRefInd(new UInt_t[fRefSize]),
  fRefBuff(new UInt_t[fRefSize])
{
  //
  // create a copy 
  //
  memcpy(fElems,src.fElems,fNElems*sizeof(Int_t));
  memcpy(fRefInd,src.fRefInd,fRefSize*sizeof(UInt_t));
  memcpy(fRefBuff,src.fRefBuff,fRefSize*sizeof(UInt_t));
}
 
//____________________________________________________________________
AliRefArray& AliRefArray::operator=(const AliRefArray& src)
{
  // create a copy with useful info (skip unused slots)
  if(&src != this) {
    TObject::operator=(src);
    fNElems = src.fNElems;
    fRefSize=0;
    if (fElems) delete[] fElems;
    if (fRefInd) delete[] fRefInd;
    if (fRefBuff) delete[] fRefBuff;
    fElems = 0;
    fRefInd = 0;
    fRefBuff = 0;
    if (src.fRefInd) {
      fRefSize = src.fRefInd[0];
      fRefInd  = new UInt_t[fRefSize];
      fRefBuff = new UInt_t[fRefSize];
      memcpy(fRefInd, src.fRefInd, fRefSize*sizeof(UInt_t));
      memcpy(fRefBuff,src.fRefBuff,fRefSize*sizeof(UInt_t));
    }
    if (fNElems) {
      fElems   = new Int_t[fNElems];   
      memcpy(fElems,src.fElems,fNElems*sizeof(Int_t));
    }
  }
  return *this;
  //
}

//____________________________________________________________________
AliRefArray::~AliRefArray() 
{
  // destructor
  delete[] fElems;
  delete[] fRefBuff;
  delete[] fRefInd;
}

//____________________________________________________________________
void AliRefArray::Expand(UInt_t size)
{
  // expand the size
  if (size<fNElems) {
    if (size>0) {printf("The size can be only increased\n");return;}
    else size = (fNElems<<2) + 1;
  }
  else if (size==fNElems) return;
  Int_t *tmpArr = new Int_t[size];
  memcpy(tmpArr,fElems,fNElems*sizeof(Int_t));
  memset(tmpArr+fNElems,0,(size-fNElems)*sizeof(UInt_t));
  delete[] fElems;
  fElems  = tmpArr;
  fNElems = size;
}

//____________________________________________________________________
void AliRefArray::Reset()
{
  // reset references
  if (fNElems) memset(fElems,0,fNElems*sizeof(Int_t));
  if (fRefSize) {
    memset(fRefInd,0,fRefSize*sizeof(UInt_t));
    memset(fRefBuff,0,fRefSize*sizeof(UInt_t));
    fRefInd[0] = 1;
  }
}

//____________________________________________________________________
void AliRefArray::ExpandReferences(Int_t addSize)
{
  // add extra slots
  if (addSize<3) addSize = 3;
  UInt_t oldSize = fRefSize;
  fRefSize += addSize;
  UInt_t*   buff = new UInt_t[fRefSize];
  UInt_t*   ind  = new UInt_t[fRefSize];
  if (fRefBuff) memcpy(buff, fRefBuff, oldSize*sizeof(UInt_t)); // copy current content
  if (fRefInd)  memcpy(ind,  fRefInd,  oldSize*sizeof(UInt_t));
  memset(buff+oldSize,0,addSize*sizeof(UInt_t));
  memset(ind +oldSize,0,addSize*sizeof(UInt_t));
  delete[] fRefBuff; fRefBuff = buff;
  delete[] fRefInd;  fRefInd  = ind;
  if (!oldSize) fRefInd[0] = 1;
}

//____________________________________________________________________
void AliRefArray::Print(Option_t*) const
{
  // reset references
  for (UInt_t i=0;i<fNElems;i++) {
    printf("Entry%4d: ",i);
    Int_t ref;
    if (!(ref=fElems[i])) {printf("None\n"); continue;}
    if (fElems[i]<0)      {printf("%d\n",-(1+ref));   continue;}
    do { printf("%d ",fRefBuff[ref]-1); }    while((ref=fRefInd[ref])); printf("\n");
  }
}

//____________________________________________________________________
void AliRefArray::AddReferences(UInt_t from, UInt_t *refs, UInt_t nref)
{
  // add nodes to the references of "from"
  if (nref==1) {AddReference(from, refs[0]); return;}
  if (!nref) return;
  //
  if (from>=fNElems) Expand(from+1);
  UInt_t chk = nref + (fElems[from]<0); // if <0, need to transfer to indices the only existing reference
  if      (!fRefInd) ExpandReferences(chk+1);
  else if ( fRefInd[0]+chk >= fRefSize ) ExpandReferences(chk);
  UInt_t &freeSlot = fRefInd[0];
  // if there is already single ref, transfer it to indices
  Int_t ref = fElems[from];
  if (ref<0) { fRefInd[freeSlot]=0; fRefBuff[freeSlot] = -ref; ref = fElems[from] = freeSlot++; }
  //
  while(fRefInd[ref]) ref=fRefInd[ref]; // find last index of last entry for cluster from
  if (fElems[from]) fRefInd[ref] = freeSlot;           // not a first entry, register it in the indices
  else              fElems[from] = freeSlot;           // first entry, register it in the refs
  for (UInt_t ir=0;ir<nref;ir++) {
    if (!ir && !fElems[from]) fElems[from] = freeSlot;
    else ref = fRefInd[ref] = freeSlot;
    fRefBuff[freeSlot++] = refs[ir]+1;
  }
}
 AliRefArray.cxx:1
 AliRefArray.cxx:2
 AliRefArray.cxx:3
 AliRefArray.cxx:4
 AliRefArray.cxx:5
 AliRefArray.cxx:6
 AliRefArray.cxx:7
 AliRefArray.cxx:8
 AliRefArray.cxx:9
 AliRefArray.cxx:10
 AliRefArray.cxx:11
 AliRefArray.cxx:12
 AliRefArray.cxx:13
 AliRefArray.cxx:14
 AliRefArray.cxx:15
 AliRefArray.cxx:16
 AliRefArray.cxx:17
 AliRefArray.cxx:18
 AliRefArray.cxx:19
 AliRefArray.cxx:20
 AliRefArray.cxx:21
 AliRefArray.cxx:22
 AliRefArray.cxx:23
 AliRefArray.cxx:24
 AliRefArray.cxx:25
 AliRefArray.cxx:26
 AliRefArray.cxx:27
 AliRefArray.cxx:28
 AliRefArray.cxx:29
 AliRefArray.cxx:30
 AliRefArray.cxx:31
 AliRefArray.cxx:32
 AliRefArray.cxx:33
 AliRefArray.cxx:34
 AliRefArray.cxx:35
 AliRefArray.cxx:36
 AliRefArray.cxx:37
 AliRefArray.cxx:38
 AliRefArray.cxx:39
 AliRefArray.cxx:40
 AliRefArray.cxx:41
 AliRefArray.cxx:42
 AliRefArray.cxx:43
 AliRefArray.cxx:44
 AliRefArray.cxx:45
 AliRefArray.cxx:46
 AliRefArray.cxx:47
 AliRefArray.cxx:48
 AliRefArray.cxx:49
 AliRefArray.cxx:50
 AliRefArray.cxx:51
 AliRefArray.cxx:52
 AliRefArray.cxx:53
 AliRefArray.cxx:54
 AliRefArray.cxx:55
 AliRefArray.cxx:56
 AliRefArray.cxx:57
 AliRefArray.cxx:58
 AliRefArray.cxx:59
 AliRefArray.cxx:60
 AliRefArray.cxx:61
 AliRefArray.cxx:62
 AliRefArray.cxx:63
 AliRefArray.cxx:64
 AliRefArray.cxx:65
 AliRefArray.cxx:66
 AliRefArray.cxx:67
 AliRefArray.cxx:68
 AliRefArray.cxx:69
 AliRefArray.cxx:70
 AliRefArray.cxx:71
 AliRefArray.cxx:72
 AliRefArray.cxx:73
 AliRefArray.cxx:74
 AliRefArray.cxx:75
 AliRefArray.cxx:76
 AliRefArray.cxx:77
 AliRefArray.cxx:78
 AliRefArray.cxx:79
 AliRefArray.cxx:80
 AliRefArray.cxx:81
 AliRefArray.cxx:82
 AliRefArray.cxx:83
 AliRefArray.cxx:84
 AliRefArray.cxx:85
 AliRefArray.cxx:86
 AliRefArray.cxx:87
 AliRefArray.cxx:88
 AliRefArray.cxx:89
 AliRefArray.cxx:90
 AliRefArray.cxx:91
 AliRefArray.cxx:92
 AliRefArray.cxx:93
 AliRefArray.cxx:94
 AliRefArray.cxx:95
 AliRefArray.cxx:96
 AliRefArray.cxx:97
 AliRefArray.cxx:98
 AliRefArray.cxx:99
 AliRefArray.cxx:100
 AliRefArray.cxx:101
 AliRefArray.cxx:102
 AliRefArray.cxx:103
 AliRefArray.cxx:104
 AliRefArray.cxx:105
 AliRefArray.cxx:106
 AliRefArray.cxx:107
 AliRefArray.cxx:108
 AliRefArray.cxx:109
 AliRefArray.cxx:110
 AliRefArray.cxx:111
 AliRefArray.cxx:112
 AliRefArray.cxx:113
 AliRefArray.cxx:114
 AliRefArray.cxx:115
 AliRefArray.cxx:116
 AliRefArray.cxx:117
 AliRefArray.cxx:118
 AliRefArray.cxx:119
 AliRefArray.cxx:120
 AliRefArray.cxx:121
 AliRefArray.cxx:122
 AliRefArray.cxx:123
 AliRefArray.cxx:124
 AliRefArray.cxx:125
 AliRefArray.cxx:126
 AliRefArray.cxx:127
 AliRefArray.cxx:128
 AliRefArray.cxx:129
 AliRefArray.cxx:130
 AliRefArray.cxx:131
 AliRefArray.cxx:132
 AliRefArray.cxx:133
 AliRefArray.cxx:134
 AliRefArray.cxx:135
 AliRefArray.cxx:136
 AliRefArray.cxx:137
 AliRefArray.cxx:138
 AliRefArray.cxx:139
 AliRefArray.cxx:140
 AliRefArray.cxx:141
 AliRefArray.cxx:142
 AliRefArray.cxx:143
 AliRefArray.cxx:144
 AliRefArray.cxx:145
 AliRefArray.cxx:146
 AliRefArray.cxx:147
 AliRefArray.cxx:148
 AliRefArray.cxx:149
 AliRefArray.cxx:150
 AliRefArray.cxx:151
 AliRefArray.cxx:152
 AliRefArray.cxx:153
 AliRefArray.cxx:154
 AliRefArray.cxx:155
 AliRefArray.cxx:156
 AliRefArray.cxx:157
 AliRefArray.cxx:158
 AliRefArray.cxx:159
 AliRefArray.cxx:160
 AliRefArray.cxx:161
 AliRefArray.cxx:162
 AliRefArray.cxx:163
 AliRefArray.cxx:164
 AliRefArray.cxx:165
 AliRefArray.cxx:166
 AliRefArray.cxx:167
 AliRefArray.cxx:168
 AliRefArray.cxx:169
 AliRefArray.cxx:170
 AliRefArray.cxx:171
 AliRefArray.cxx:172
 AliRefArray.cxx:173
 AliRefArray.cxx:174
 AliRefArray.cxx:175
 AliRefArray.cxx:176
 AliRefArray.cxx:177
 AliRefArray.cxx:178
 AliRefArray.cxx:179
 AliRefArray.cxx:180
 AliRefArray.cxx:181
 AliRefArray.cxx:182
 AliRefArray.cxx:183
 AliRefArray.cxx:184