#include "TEntryListArray.h"
#include "TEntryListBlock.h"
#include "TTree.h"
#include "TFile.h"
#include "TSystem.h"
#include <iostream>
ClassImp(TEntryListArray)
void TEntryListArray::Init()
{
fSubLists = 0;
fEntry = -1;
fLastSubListQueried = 0;
fSubListIter = 0;
}
TEntryListArray::TEntryListArray() : TEntryList(), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
}
TEntryListArray::TEntryListArray(const char *name, const char *title): TEntryList(name, title), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
}
TEntryListArray::TEntryListArray(const char *name, const char *title, const TTree *tree): TEntryList(name, title, tree), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
}
TEntryListArray::TEntryListArray(const char *name, const char *title, const char *treename, const char *filename): TEntryList(name, title, treename, filename), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
}
TEntryListArray::TEntryListArray(const TTree *tree) : TEntryList(tree), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
}
TEntryListArray::TEntryListArray(const TEntryListArray &elist) : TEntryList(), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
fEntry = elist.fEntry;
Add(&elist);
}
TEntryListArray::TEntryListArray(const TEntryList& elist) : TEntryList(elist), fSubLists(0), fEntry(-1), fLastSubListQueried(0), fSubListIter(0)
{
}
TEntryListArray::~TEntryListArray()
{
if (fSubLists) {
fSubLists->Delete();
delete fSubLists;
}
fSubLists = 0;
delete fSubListIter;
fSubListIter = 0;
}
void TEntryListArray::Add(const TEntryList *elist)
{
if (!elist) return;
if (fEntry != -1) {
TEntryList::Add(elist);
return;
}
if (elist->GetLists()) {
TIter next(elist->GetLists());
const TEntryList *e = 0;
while ((e = (const TEntryList*)next())) {
SetTree(e->GetTreeName(), e->GetFileName());
}
} else {
SetTree(elist->GetTreeName(), elist->GetFileName());
}
AddEntriesAndSubLists(elist);
}
void TEntryListArray::AddEntriesAndSubLists(const TEntryList *elist)
{
if (!elist) return;
if (fLists) {
TEntryListArray* e = 0;
TIter next(fLists);
fN = 0;
while ((e = (TEntryListArray*) next())) {
e->AddEntriesAndSubLists(elist);
fN += e->GetN();
}
} else if (elist->GetLists()) {
TIter next(elist->GetLists());
TEntryList *e = 0;
while ((e = (TEntryList*) next())) {
AddEntriesAndSubLists(e);
}
} else {
if (strcmp(elist->GetTreeName(), fTreeName.Data()) || strcmp(elist->GetFileName(), fFileName.Data()))
return;
const TEntryListArray *elist_array = dynamic_cast< const TEntryListArray *>(elist);
if (!fSubLists && (!elist_array || !elist_array->GetSubLists())) {
TEntryList::Add(elist);
return;
}
if (!fSubLists && elist_array->GetSubLists()) {
fSubLists = new TList();
}
TEntryListArray *el1;
const TEntryListArray *el2;
TCollection *other_sublists = 0;
if (elist_array) {
other_sublists = elist_array->GetSubLists();
}
TIter next1(fSubLists);
TIter next2(other_sublists);
for (el1 = (TEntryListArray*) next1(), el2 = (const TEntryListArray*) next2(); el1 || el2;) {
if (el1 && el2 && el1->fEntry == el2->fEntry) {
el1->TEntryList::Add(el2);
el1 = (TEntryListArray*) next1();
el2 = (const TEntryListArray*) next2();
} else if (el1 && (!el2 || el1->fEntry < el2->fEntry)) {
if ((const_cast<TEntryList*>(elist))->Contains(el1->fEntry)) {
RemoveSubList(el1);
}
el1 = (TEntryListArray*) next1();
} else {
if (!Contains(el2->fEntry)) {
if (!el1) {
fSubLists->AddLast(new TEntryListArray(*el2));
} else {
fSubLists->AddBefore(el1, new TEntryListArray(*el2));
}
}
el2 = (const TEntryListArray*) next2();
}
}
TEntryList::Add(elist);
}
}
Int_t TEntryListArray::Contains(Long64_t entry, TTree *tree, Long64_t subentry)
{
if (tree) {
Long64_t localentry = tree->LoadTree(entry);
SetTree(tree->GetTree());
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray) {
return currentArray->Contains(localentry, 0, subentry);
}
return 0;
}
Int_t result = TEntryList::Contains(entry);
if (result && fSubLists) {
TEntryListArray *t = GetSubListForEntry(entry);
if (t) {
result = t->TEntryList::Contains(subentry);
}
}
return result;
}
void TEntryListArray::ConvertToTEntryListArray(TEntryList *e)
{
TEntryListArray *earray = new TEntryListArray(*e);
if (e == fCurrent) {
fCurrent = earray;
}
if (fSubLists) {
earray->fSubLists = fSubLists;
fSubLists = 0;
}
if (e == fLists->First()) {
fLists->AddFirst(earray);
} else {
fLists->Add(earray);
}
fLists->Remove(e);
delete e;
e = 0;
}
Bool_t TEntryListArray::Enter(Long64_t entry, TTree *tree, Long64_t subentry)
{
Bool_t result = 0;
if (tree) {
Long64_t localentry = tree->LoadTree(entry);
SetTree(tree->GetTree());
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray) {
if ((result = currentArray->Enter(localentry, 0, subentry)))
if (fLists) ++fN;
}
return result;
}
if (fLists) {
if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray && (result = currentArray->Enter(entry, 0, subentry))) {
++fN;
}
return result;
}
TEntryListArray *t = GetSubListForEntry(entry);
if (t) {
if (subentry != -1) {
t->TEntryList::Enter(subentry);
} else {
RemoveSubList(t);
}
} else {
result = TEntryList::Enter(entry);
if (subentry != -1 && result) {
t = SetEntry(entry);
if (t) t->TEntryList::Enter(subentry);
}
}
return result;
}
TEntryListArray* TEntryListArray::GetSubListForEntry(Long64_t entry, TTree *tree)
{
if (tree) {
Long64_t localentry = tree->LoadTree(entry);
SetTree(tree->GetTree());
if (fCurrent) {
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray) {
return currentArray->GetSubListForEntry(localentry);
}
}
return 0;
}
if (!fSubLists || !fSubLists->GetEntries()) {
return 0;
}
if (!fSubListIter) {
fSubListIter = new TIter(fSubLists);
fLastSubListQueried = (TEntryListArray*) fSubListIter->Next();
}
else if (!fLastSubListQueried || entry < fLastSubListQueried->fEntry) {
fSubListIter->Reset();
fLastSubListQueried = (TEntryListArray*) fSubListIter->Next();
}
if (entry == fLastSubListQueried->fEntry) {
return fLastSubListQueried;
}
while ((fLastSubListQueried = (TEntryListArray*) fSubListIter->Next())) {
if (fLastSubListQueried->fEntry == entry) {
return fLastSubListQueried;
}
if (fLastSubListQueried->fEntry > entry) {
break;
}
}
return 0;
}
void TEntryListArray::Print(const Option_t* option) const
{
TString opt = option;
opt.ToUpper();
Bool_t new_line = !opt.Contains("EOL");
if (!opt.Contains("S") && new_line) {
TEntryList::Print(option);
return;
}
if (fLists) {
TIter next(fLists);
TEntryListArray *e = 0;
while ((e = (TEntryListArray*)next())) {
std::cout << e->fTreeName << ":" << std::endl;
e->Print(option);
}
return;
}
TEntryListArray *tmp = const_cast<TEntryListArray *>(this);
TIter next(fSubLists);
TEntryListArray *e = (TEntryListArray*)next();
for (Int_t i = 0; i < tmp->fN; ++i) {
Long64_t entry = tmp->GetEntry(i);
std::cout << entry << " ";
if (fSubLists) {
std::cout << " : ";
}
if (e && e->fEntry == entry) {
e->Print("all,EOL");
e = (TEntryListArray*)next();
}
if (new_line) {
std::cout << std::endl;
}
}
}
Bool_t TEntryListArray::Remove(Long64_t entry, TTree *tree, Long64_t subentry)
{
Bool_t result = 0;
if (tree) {
Long64_t localentry = tree->LoadTree(entry);
SetTree(tree->GetTree());
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray && (result = currentArray->Remove(localentry, 0, subentry))) {
if (fLists) {
--fN;
}
}
return result;
}
if (fLists) {
if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray && (result = currentArray->Remove(entry, 0, subentry)) && fLists) {
--fN;
}
return result;
}
TEntryListArray *e = GetSubListForEntry(entry);
if (e) {
if (subentry != -1) {
e->TEntryList::Remove(subentry);
}
if (subentry == -1 || !e->GetN()) {
RemoveSubList(e, tree);
return TEntryList::Remove(entry);
}
} else if (subentry == -1) {
return TEntryList::Remove(entry);
}
return 0;
}
Bool_t TEntryListArray::RemoveSubList(TEntryListArray *e, TTree *tree)
{
if (!e) return 0;
if (tree) {
SetTree(tree->GetTree());
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray) {
return currentArray->RemoveSubList(e);
}
}
if (!fSubLists->Remove(e)) {
return 0;
}
delete e;
e = 0;
if (!fSubLists->GetEntries()) {
delete fSubLists;
fSubLists = 0;
}
return 1;
}
Bool_t TEntryListArray::RemoveSubListForEntry(Long64_t entry, TTree *tree)
{
if (tree) {
Long64_t localentry = tree->LoadTree(entry);
SetTree(tree->GetTree());
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray) {
return currentArray->RemoveSubListForEntry(localentry);
}
}
return RemoveSubList(GetSubListForEntry(entry));
}
void TEntryListArray::Reset()
{
TEntryList::Reset();
if (fSubLists) {
if (!((TEntryListArray*)fSubLists->First())->GetDirectory()) {
fSubLists->Delete();
}
delete fSubLists;
}
delete fSubListIter;
Init();
}
TEntryListArray* TEntryListArray::SetEntry(Long64_t entry, TTree *tree)
{
if (entry < 0) return 0;
if (tree) {
Long64_t localentry = tree->LoadTree(entry);
SetTree(tree->GetTree());
TEntryListArray *currentArray = dynamic_cast<TEntryListArray*>(fCurrent);
if (currentArray) {
return currentArray->SetEntry(localentry);
}
return 0;
}
if (!fSubLists) {
fSubLists = new TList();
}
TEntryListArray *newlist = new TEntryListArray();
newlist->fEntry = entry;
if (fLastSubListQueried) {
fSubLists->AddBefore(fLastSubListQueried, newlist);
fSubListIter->Reset();
} else {
fSubLists->AddLast(newlist);
}
fLastSubListQueried = newlist;
return newlist;
}
void TEntryListArray::Subtract(const TEntryList *elist)
{
if (!elist) return;
if (fLists) {
TEntryListArray* e = 0;
TIter next(fLists);
fN = 0;
while ((e = (TEntryListArray*) next())) {
e->Subtract(elist);
fN += e->GetN();
}
} else if (elist->GetLists()) {
TIter next(elist->GetLists());
TEntryList *e = 0;
while ((e = (TEntryList*) next())) {
Subtract(e);
}
} else {
if (strcmp(elist->GetTreeName(), fTreeName.Data()) || strcmp(elist->GetFileName(), fFileName.Data()))
return;
const TEntryListArray *elist_array = dynamic_cast< const TEntryListArray *>(elist);
if (!fSubLists || !elist_array || !elist_array->GetSubLists()) {
TEntryList::Subtract(elist);
if (fSubLists) {
TEntryListArray *e = 0;
TIter next(fSubLists);
while ((e = (TEntryListArray*) next())) {
if (!Contains(e->fEntry))
RemoveSubList(e);
}
}
} else {
TEntryListArray *el1, *el2;
TIter next1(fSubLists);
TIter next2(elist_array->GetSubLists());
el1 = (TEntryListArray*) next1();
el2 = (TEntryListArray*) next2();
Long64_t n2 = elist->GetN();
Long64_t entry;
for (Int_t i = 0; i < n2; ++i) {
entry = (const_cast<TEntryList*>(elist))->GetEntry(i);
while (el1 && el1->fEntry < entry) {
el1 = (TEntryListArray*) next1();
}
while (el2 && el2->fEntry < entry) {
el2 = (TEntryListArray*) next2();
}
if (el1 && el2 && entry == el1->fEntry && entry == el2->fEntry) {
el1->Subtract(el2);
if (!el1->fN) {
Remove(entry);
}
} else {
Remove(entry);
}
}
}
}
}
void TEntryListArray::SetTree(const char *treename, const char *filename)
{
Int_t nLists = -1;
if (fLists) {
nLists = fLists->GetEntries();
}
TEntryList::SetTree(treename, filename);
if (fLists && fLists->GetEntries() != nLists) {
if (nLists == -1) {
ConvertToTEntryListArray((TEntryList*) fLists->First());
}
ConvertToTEntryListArray((TEntryList*) fLists->Last());
}
}