Files
geant4/source/analysis/g4tools/include/tools/rroot/branch
T
2016-06-10 14:11:04 +02:00

949 lines
27 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_rroot_branch
#define tools_rroot_branch
#include "base_leaf"
#include "basket"
#include "named"
#include "seek"
#include "ifile"
#include "ifac"
#include "../mnmx"
#include "../forit"
#include "../sprintf"
#include <map>
namespace tools {
namespace rroot {
class branch : public virtual iro {
//static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
public:
static const std::string& s_class() {
static const std::string s_v("tools::rroot::branch");
return s_v;
}
public: //iro
virtual void* cast(const std::string& a_class) const {
if(void* p = cmp_cast<branch>(this,a_class)) return p;
return 0;
}
virtual const std::string& s_cls() const {return s_class();}
public:
static cid id_class() {return branch_cid();}
virtual void* cast(cid a_class) const {
if(void* p = cmp_cast<branch>(this,a_class)) {return p;}
else return 0;
}
public:
virtual iro* copy() const {return new branch(*this);}
virtual bool stream(buffer& a_buffer) {
_clear();
int fCompress;
int fBasketSize;
//int fNleaves;
//uint64 m_entries;
//uint64 m_tot_bytes;
//uint64 m_zip_bytes;
int fSplitLevel;
uint32 fMaxBaskets;
int fOffset;
unsigned int s,c;
//FIXME gROOT->SetReadingObject(kTRUE);
short vers;
if(!a_buffer.read_version(vers,s,c)) return false;
//::printf("debug : branch::stream : version %d count %d\n",vers,c);
if (vers > 5) {
//TBranch::Class()->ReadBuffer(b, this, v, s, c);
//gBranch = branchSave;
//fDirectory = gDirectory;
//fNleaves = m_leaves.GetEntriesFast();
//if (fFileName.Length() != 0) fDirectory = 0;
//gROOT->SetReadingObject(kFALSE);
//return;
}
//====process old versions before automatic schema evolution
{uint32 old = a_buffer.length();
uint32 id;
uint32 m_bits;
if(!Object_stream(a_buffer,id,m_bits)) return false;
a_buffer.set_offset(old);}
if(!Named_stream(a_buffer,m_name,m_title)) return false;
//::printf("debug : branch::stream %s %s\n",
// m_name.c_str(),m_title.c_str());
if(vers<=5) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
if(!a_buffer.read(fOffset)) return false;
} else if(vers<=6) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=7) {
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=9) {
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
if(!a_buffer.read(m_entry_number)) return false;
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{double v;
if(!a_buffer.read(v)) return false;
//m_entries = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = uint64(v);
}
{double v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = uint64(v);
}
} else if(vers<=10) {
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entry_number = uint32(v);}
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_entries = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
} else { //vers>=11
{short color,style;
if(!AttFill_stream(a_buffer,color,style)) return false;}
if(!a_buffer.read(fCompress)) return false;
if(!a_buffer.read(fBasketSize)) return false;
if(!a_buffer.read(fEntryOffsetLen)) return false;
if(!a_buffer.read(m_write_basket)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
m_entry_number = uint32(v);}
if(!a_buffer.read(fOffset)) return false;
if(!a_buffer.read(fMaxBaskets)) return false;
if(!a_buffer.read(fSplitLevel)) return false;
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_entries = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;} //fFirstEntry
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_tot_bytes = v;
}
{uint64 v;
if(!a_buffer.read(v)) return false;
//m_zip_bytes = v;
}
}
//::printf("debug : branch::stream : %s : fSplitLevel %d\n",m_name.c_str(),fSplitLevel);
//TObjArray
//::printf("debug : branch::stream : branches : begin\n");
{ifac::args args;
if(!m_branches.stream(a_buffer,args)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read branches."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : branches : end %d\n",
// m_branches.size());
/* We see that with LHCb files.
if(m_entry_number!=m_entries) {
m_out << "tools::rroot::branch::stream :"
<< " for branch " << sout(m_name) << " :"
<< " WARNING : m_entry_number!=m_entries."
<< " m_entry_number " << m_entry_number
<< " m_entries " << m_entries
<< std::endl;
//return false;
}
*/
//TObjArray
//::printf("debug : branch::stream : leaves : begin\n");
{ifac::args args;
args[ifac::arg_branch()] = this;
if(!m_leaves.stream(a_buffer,args)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read leaves."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : leaves : end\n");
//TObjArray
//IMPORTANT : accept_null=true
//::printf("debug : branch::stream : streamed_baskets : begin\n");
{ifac::args args;
if(!m_streamed_baskets.stream(a_buffer,args,true)) {
m_out << "tools::rroot::branch::stream :"
<< " can't read baskets."
<< std::endl;
return false;
}}
//::printf("debug : branch::stream : streamed_baskets : end\n");
//fNleaves = m_leaves.size();
if(fMaxBaskets<=0) {
m_out << "tools::rroot::branch::stream :"
<< " fMaxBaskets null."
<< std::endl;
return false;
}
fBasketEntry = new int[fMaxBaskets];
fBasketBytes = new int[fMaxBaskets];
fBasketSeek = new seek[fMaxBaskets];
{for(uint32 i=0;i<fMaxBaskets;i++) {
fBasketEntry[i] = 0;
fBasketBytes[i] = 0;
fBasketSeek[i] = 0;
}}
if(vers<6) {
{uint32 n;
if(!a_buffer.read_array<int>(fMaxBaskets,fBasketEntry,n)) {
_clear();
return false;
}}
if(vers<=4) {
for (uint32 i=0;i<fMaxBaskets;i++) fBasketBytes[i] = 0;
} else {
uint32 n;
if(!a_buffer.read_array<int>(fMaxBaskets,fBasketBytes,n)) {
_clear();
return false;
}
}
if(vers<2) {
//GB : comment.
//for(int i=0;i<m_write_basket;i++) {
// fBasketSeek[i] = getBasket(i)->seekKey();
//}
m_out << "tools::rroot::branch::stream :"
<< " v < 2. Not (yet) handled."
<< std::endl;
_clear();
return false;
} else {
int n;
if(!a_buffer.read(n)) {
_clear();
return false;
}
for(int i=0;i<n;i++) {
seek32 _s;
if(!a_buffer.read(_s)) {
_clear();
return false;
}
fBasketSeek[i] = _s;
}
}
} else if(vers<=9) {
// See TStreamerInfo::ReadBuffer::ReadBasicPointer
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
_clear();
return false;
}
}}
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketEntry,fMaxBaskets)) {
_clear();
return false;
}
}}
//Seek_t[fMaxBaskets]
{char isBigFile;
if(!a_buffer.read(isBigFile)) {
_clear();
return false;
}
if(isBigFile==2) {
if(!a_buffer.read_fast_array<seek>(fBasketSeek,fMaxBaskets)) {
_clear();
return false;
}
} else {
for(uint32 i=0;i<fMaxBaskets;i++) {
seek32 _s;
if(!a_buffer.read(_s)) {
_clear();
return false;
}
fBasketSeek[i] = _s;
}
}}
} else { //vers>=10
// See TStreamerInfo::ReadBuffer::ReadBasicPointer
//Int_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
_clear();
return false;
}
}}
//Long64_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
uint64* v = new uint64[fMaxBaskets];
if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
_clear();
return false;
}
for(uint32 i=0;i<fMaxBaskets;i++) fBasketEntry[i] = int(v[i]);
delete [] v;
}}
//Long64_t[fMaxBaskets]
{char isArray;
if(!a_buffer.read(isArray)) {
_clear();
return false;
}
if(isArray) {
uint64* v = new uint64[fMaxBaskets];
if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
_clear();
return false;
}
for(uint32 i=0;i<fMaxBaskets;i++) fBasketSeek[i] = v[i];
delete [] v;
}}
}
if(vers>2) {
//TString
std::string fileName;
if(!a_buffer.read(fileName)) {
_clear();
return false;
}
}
//FIXME if(vers<4) SetAutoDelete(kTRUE);
//FIXME gROOT->SetReadingObject(kFALSE);
if(!a_buffer.check_byte_count(s, c,"TBranch")) {
_clear();
return false;
}
//GB : analyse fBasketEntry.
m_first_last.clear();
{// There are (m_write_basket+1) sensitive elements in fBasketEntry :
// (Do we have to check that ?)
for(uint32 i=0;i<m_write_basket;i++) {
uint32 first = fBasketEntry[i];
uint32 last = fBasketEntry[i+1]-1;
m_first_last.push_back(std::pair<uint32,uint32>(first,last));
}
if(m_entry_number) {
uint32 first = fBasketEntry[m_write_basket];
uint32 last = m_entry_number-1;
m_first_last.push_back(std::pair<uint32,uint32>(first,last));
}}
//_dump_first_last();
//GB : analyse fBasketSeek :
{uint32 num = 0;
uint32 mxi = 0;
for(uint32 i=0;i<fMaxBaskets;i++) {
if(!fBasketSeek[i]) continue;
num++;
mxi = mx<uint32>(i,mxi);
}
if(m_write_basket) {
if((num!=m_write_basket)||(mxi!=(m_write_basket-1))) {
m_out << "tools::rroot::branch::stream :"
<< " fBasketSeek[] inconsistent with m_write_basket."
<< " m_write_basket " << m_write_basket
<< " num " << num
<< " mxi " << mxi
<< std::endl;
_clear();
return false;
}
}}
//GB : analyse m_streamed_baskets :
{int index = 0;
tools_vforcit(basket*,m_streamed_baskets,it) {
if(*it) {
if(!(*it)->buf()||!(*it)->buf_size()) {
m_out << "tools::rroot::branch::stream :"
<< " expect a basket with a not empty buffer."
<< std::endl;
return false;
}
//in the below, false is to say m_baskets is not owner of *it.
m_baskets[index] = std::pair<basket*,bool>(*it,false);
}
index++;
}}
return true;
}
public:
//virtual for branch_element
virtual bool read_leaves(buffer& a_buffer){
tools_vforcit(base_leaf*,m_leaves,it) {
if(!(*it)->read_basket(a_buffer)) {
m_out << "tools::rroot::branch::read_leaves :"
<< " read_basket failed."
<< std::endl;
return false;
}
}
return true;
}
virtual bool find_entry(uint32 a_entry,uint32& a_nbytes){
// Read all leaves of entry and return total number of bytes :
// The input argument entry is the entry serial number in the current tree.
a_nbytes = 0;
//if(_test_bit(kDoNotProcess())) return true;
//if(fReadEntry == (int)a_entry) return true;
if(a_entry>=m_entry_number) {
//m_out << "tools::rroot::branch::find_entry :"
// << " for branch " << sout(m_name) << " :"
// << " a_entry not within [0," << m_entry_number << "[."
// << std::endl;
//return false;
return true; //CERN-ROOT does not consider it is an error.
}
if(!m_entry_number || m_first_last.empty() ) { //GB
m_out << "tools::rroot::branch::find_entry :"
<< " nothing to read."
<< std::endl;
return false; //nothing to read.
}
if(m_read_basket>=m_first_last.size()) {
m_out << "tools::rroot::branch::find_entry :"
<< " bad m_first_last access."
<< std::endl;
return false;
}
uint32 first = m_first_last[m_read_basket].first;
uint32 last = m_first_last[m_read_basket].second;
// Are we still in the same ReadBasket?
if((a_entry<first)||(a_entry>last)) {
m__read_basket = 0;
uint32 old_read_basket = m_read_basket;
//look first in the next basket window :
bool found = false;
if((m_read_basket+1)<m_first_last.size()) {
first = m_first_last[m_read_basket+1].first;
last = m_first_last[m_read_basket+1].second;
if((a_entry>=first)&&(a_entry<=last)) {
m_read_basket++;
found = true;
}
}
if(!found) {
uint32 count = 0;
typedef std::pair<uint32,uint32> first_last;
tools_vforcit(first_last,m_first_last,it) {
first = (*it).first;
last = (*it).second;
if((a_entry>=first)&&(a_entry<=last)) {
m_read_basket = count;
found = true;
break;
}
count++;
}
}
if(!found) { //something weird in fBasketEntry.
m_out << "tools::rroot::branch::find_entry :"
<< " fancy fBasketEntry."
<< std::endl;
return false;
} else {
// if found, erase m_baskets[old_read_basket] to avoid
// having all data in memory !
std::map<uint32, std::pair<rroot::basket*,bool> >::iterator it = m_baskets.find(old_read_basket);
if(it!=m_baskets.end()) {
if((*it).second.second) {
basket* bsk = (*it).second.first;
m_baskets.erase(it);
delete bsk;
//::printf("debug : erase basket %d\n",old_read_basket);
}
}
}
}
if(!m__read_basket) {
rroot::basket* bsk = 0;
std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(m_read_basket);
if(it!=m_baskets.end()) {
bsk = (*it).second.first;
} else {
if(m_read_basket>=m_write_basket) {
m_out << "tools::rroot::branch::find_entry :"
<< " basket lacking !"
<< " wanting index " << m_read_basket
<< ". fBasketSeek entries " << m_write_basket
<< std::endl;
return false;
}
if(!fBasketSeek[m_read_basket]) {
m_out << "tools::rroot::branch::find_entry :"
<< " fBasketSeek is null for index " << m_read_basket
<< std::endl;
return false;
}
if(!fBasketBytes[m_read_basket]) {
m_out << "tools::rroot::branch::find_entry :"
<< " fBasketBytes is null for index " << m_read_basket
<< std::endl;
return false;
}
bsk = get_basket(fBasketSeek[m_read_basket],fBasketBytes[m_read_basket]);
if(!bsk) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't read basket " << m_read_basket
<< " at file pos " << fBasketSeek[m_read_basket]
<< " and size " << fBasketBytes[m_read_basket]
<< std::endl;
return false;
}
//m_out << "tools::rroot::branch::find_entry :"
// << " got basket " << m_read_basket
// << " of size " << fBasketBytes[m_read_basket]
// << std::endl;
m_baskets[m_read_basket] = std::pair<basket*,bool>(bsk,true);
}
m__read_basket = bsk;
}
// Set entry offset in buffer and read data from all leaves
//buf->resetMap();
uint32 bufbegin;
{int* entry_offset = m__read_basket->entry_offset();
if(entry_offset) {
uint32 index = a_entry-first;
if(index>=m__read_basket->nev()) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't access entry offset " << index
<< ". nev " << m__read_basket->nev()
<< std::endl;
return false;
}
bufbegin = entry_offset[index];
//::printf("debug : xxx++ %u : %u\n",index,bufbegin);
} else {
bufbegin = m__read_basket->key_length() + (a_entry-first)*m__read_basket->nev_buf_size();
}}
{int* displacement = m__read_basket->displacement();
if(displacement) {
m_out << "tools::rroot::branch::find_entry :"
<< " not null displacement. Not yet handled."
<< std::endl;
//buf->setDisplacement(displacement[a_entry-first]);
} else {
//buf->setDisplacement();
}}
/*
if(bufbegin>=m__read_basket->buf_size()) {
m_out << "tools::rroot::branch::find_entry :"
<< " bad buffer access for entry " << a_entry
<< ". bufbegin " << bufbegin
<< ", buf_size " << basket->buf_size()
<< ", (entry-first) " << (a_entry-first)
<< std::endl;
{int* entry_offset = m__read_basket->entry_offset();
if(entry_offset) {
uint32 nev = m__read_basket->nev();
::printf("debug : eoff : num %d\n",nev);
for(uint32 i=0;i<nev;i++){
::printf("debug : eoff %d : %d\n",i,entry_offset[i]);
}
}}
return false;
}
*/
rroot::buffer buffer(m_out,m_file.byte_swap(),m__read_basket->buf_size(),m__read_basket->buf(),0,false);
buffer.set_offset(bufbegin);
if(!read_leaves(buffer)) {
m_out << "tools::rroot::branch::find_entry :"
<< " can't read leaves for entry " << a_entry
<< ". read_basket was " << m_read_basket
<< ", first " << first
<< ", last " << last
<< "."
<< std::endl;
return false;
}
//fReadEntry = a_entry;
a_nbytes = buffer.length() - bufbegin;
return true;
}
public:
branch(ifile& a_file,ifac& a_fac)
:m_file(a_file)
,m_out(a_file.out())
,m_fac(a_fac)
,m_streamed_baskets(m_fac,true)
,m__read_basket(0)
//,m_bits(0)
,m_name("")
,m_title("")
,fAutoDelete(false)
,m_branches(m_fac,true)
,m_leaves(m_fac,true)
,fEntryOffsetLen(0)
,m_write_basket(0)
,m_entry_number(0)
,m_read_basket(0)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
}
virtual ~branch(){
_clear();
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
protected:
branch(const branch& a_from)
:iro(a_from)
,m_file(a_from.m_file),m_out(a_from.m_out),m_fac(a_from.m_fac)
,m_streamed_baskets(m_fac,false),m__read_basket(0)
,fAutoDelete(false)
,m_branches(m_fac,false),m_leaves(m_fac,false)
,fEntryOffsetLen(1000)
,m_write_basket(0)
,m_entry_number(0)
,m_read_basket(0)
,fBasketBytes(0)
,fBasketEntry(0)
,fBasketSeek(0)
{}
branch& operator=(const branch&){return *this;}
public:
ifile& file() {return m_file;}
uint32 entry_number() const {return m_entry_number;}
const std::string& name() const {return m_name;}
const std::string& title() const {return m_title;}
const std::vector<base_leaf*>& leaves() const {return m_leaves;}
const std::vector<branch*>& branches() const {return m_branches;}
bool show(std::ostream& a_out,uint32 a_entry){
// Print values of all active leaves for entry :
// if entry==-1, print current entry (default)
uint32 n;
if(!find_entry(a_entry,n)) return false;
tools_vforcit(base_leaf*,m_leaves,it) {
base_leaf* bl = *it;
uint32 num = bl->num_elem();
num = mn<uint32>(num,10);
if(!num) continue;
{std::string s;
uint32 len = bl->name().size()+128;
sprintf(s,len," %-15s = ",bl->name().c_str());
a_out << s;}
for(uint32 i=0;i<num;i++) {
if(i) a_out << ", ";
bl->print_value(a_out,i);
}
a_out << std::endl;
}
return true;
}
protected:
basket* get_basket(seek a_pos,uint32 a_len) {
//if(fBranch.tree().memoryFull(fBufferSize)) fBranch.dropBaskets();
if(!a_len) return 0;
rroot::basket* basket =
new rroot::basket(m_file,a_pos,a_len); //basket is a key.
if(!basket->read_file()) {
m_out << "tools::rroot::branch::get_basket :"
<< " read_file() failed."
<< std::endl;
delete basket;
return 0;
}
{rroot::buffer buffer(m_out,m_file.byte_swap(),
a_len,basket->buf(),0,false);
if(!basket->stream(buffer)) {
m_out << "tools::rroot::branch::get_basket :"
<< " basket stream failed."
<< std::endl;
delete basket;
return 0;
}}
unsigned int sz;
char* buf = basket->get_object_buffer(sz); //basket owns buf.
if(!buf) {
m_out << "tools::rroot::branch::get_basket :"
<< " get_object_buffer() failed."
<< std::endl;
delete basket;
return 0;
}
if(basket->seek_key()!=a_pos) { //consistency check.
m_out << "tools::rroot::branch::get_basket :"
<< " seek anomaly."
<< " a_pos " << a_pos
<< " seek_key() " << basket->seek_key()
<< std::endl;
delete basket;
return 0;
}
//if(basket->nbytes()!=a_len) { //consistency check.
// m_out << "tools::rroot::branch::get_basket :"
// << " WARNING : length anomaly."
// << " a_len " << a_len
// << " nbytes() " << basket->nbytes()
// << std::endl;
//}
if(fEntryOffsetLen) {
if(!basket->read_offset_tables()) {
m_out << "tools::rroot::branch::get_basket :"
<< " read_offset_tables failed."
<< std::endl;
delete basket;
return 0;
}}
return basket;
}
protected:
void _clear() {
delete [] fBasketEntry;
delete [] fBasketBytes;
delete [] fBasketSeek;
fBasketEntry = 0;
fBasketBytes = 0;
fBasketSeek = 0;
{typedef std::pair<basket*,bool> basket_todel;
tools_mforit(uint32,basket_todel,m_baskets,it) {
if((*it).second.second) delete (*it).second.first;
}
m_baskets.clear();}
m_branches.cleanup();
m_leaves.cleanup();
m_streamed_baskets.cleanup();
}
void _dump_first_last() {
m_out << "tools::rroot::branch::_dump_first_last :"
<< " first_last " << m_first_last.size()
<< std::endl;
typedef std::pair<uint32,uint32> first_last;
tools_vforcit(first_last,m_first_last,it) {
uint32 first = (*it).first;
uint32 last = (*it).second;
m_out << "tools::rroot::branch::stream :"
<< " first " << first
<< " last " << last
<< std::endl;
}
}
//bool _test_bit(uint32 a_f) const {
// return (bool)(m_bits & a_f);
//}
protected:
//Tree& fTree;
ifile& m_file;
std::ostream& m_out;
ifac& m_fac;
std::vector< std::pair<uint32,uint32> > m_first_last;
std::map<uint32, std::pair<basket*,bool> > m_baskets;
ObjArray<basket> m_streamed_baskets;
basket* m__read_basket; //optimization
protected:
//Object
//uint32 m_bits;
//Named
std::string m_name;
std::string m_title;
bool fAutoDelete;
ObjArray<branch> m_branches;
ObjArray<base_leaf> m_leaves;
uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers
uint32 m_write_basket; // Last basket number written
uint32 m_entry_number; // Current entry number (last one filled in this branch)
uint32 m_read_basket; //! Current basket number when reading
int* fBasketBytes; //[fMaxBaskets] Lenght of baskets on file
int* fBasketEntry; //[fMaxBaskets] Table of first entry in eack basket
seek* fBasketSeek; //[fMaxBaskets] Addresses of baskets on file
};
}}
#endif