Import Geant4 10.3.0 source tree
This commit is contained in:
@@ -6,15 +6,14 @@
|
||||
|
||||
#include "leaf"
|
||||
#include "basket"
|
||||
#include "itree"
|
||||
#include "idir"
|
||||
#include "../forit"
|
||||
|
||||
#include "imutex"
|
||||
|
||||
namespace tools {
|
||||
namespace wroot {
|
||||
|
||||
class branch : public virtual ibo {
|
||||
static uint32 START_BIG_FILE() {return 2000000000;}
|
||||
//static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
|
||||
#ifdef TOOLS_MEM
|
||||
static const std::string& s_class() {
|
||||
@@ -34,7 +33,6 @@ public: //ibo
|
||||
|
||||
if(!AttFill_stream(a_buffer)) return false;
|
||||
|
||||
int fCompress = m_tree.dir().file().compression();
|
||||
int fEntryOffsetLen = 1000;
|
||||
int fOffset = 0;
|
||||
int fSplitLevel = 0;
|
||||
@@ -59,6 +57,22 @@ public: //ibo
|
||||
if(!m_leaves.stream(a_buffer)) return false;
|
||||
if(!m_baskets.stream(a_buffer)) return false;
|
||||
|
||||
/*
|
||||
{uint32 remaining_baskets = 0;
|
||||
for(uint32 i=0;i<m_max_baskets;i++) {
|
||||
if(m_baskets[i]) {
|
||||
m_out << "debug : remaining basket : index " << i << ", bytes = " << m_baskets[i]->number_of_bytes()
|
||||
<< std::endl;
|
||||
remaining_baskets++;
|
||||
}
|
||||
}
|
||||
m_out << "tools::wroot::branch::stream :"
|
||||
<< " write_basket = " << m_write_basket
|
||||
<< ", max_baskets = " << m_max_baskets
|
||||
<< ", remaining_baskets = " << remaining_baskets << "."
|
||||
<< std::endl;}
|
||||
*/
|
||||
|
||||
// See TStreamerInfo::ReadBuffer::WriteBasicPointer
|
||||
if(!a_buffer.write((char)1)) return false;
|
||||
if(!a_buffer.write_fast_array(fBasketBytes,m_max_baskets)) return false;
|
||||
@@ -101,17 +115,19 @@ public: //ibo
|
||||
}
|
||||
|
||||
public:
|
||||
branch(itree& a_tree,
|
||||
const std::string& a_name,
|
||||
const std::string& a_title)
|
||||
:m_tree(a_tree)
|
||||
,m_out(a_tree.dir().file().out())
|
||||
branch(std::ostream& a_out,bool a_byte_swap,uint32 a_compression,
|
||||
seek a_seek_directory,const std::string& a_name,const std::string& a_title,bool a_verbose)
|
||||
:m_out(a_out)
|
||||
,m_byte_swap(a_byte_swap)
|
||||
,m_verbose(a_verbose)
|
||||
,m_seek_directory(a_seek_directory)
|
||||
,m_name(a_name)
|
||||
,m_title(a_title)
|
||||
,fAutoDelete(false)
|
||||
|
||||
//,m_branches(true)
|
||||
//,m_leaves(true)
|
||||
,fCompress(a_compression)
|
||||
,m_basket_size(32000)
|
||||
,m_write_basket(0)
|
||||
,m_entry_number(0)
|
||||
@@ -126,26 +142,32 @@ public:
|
||||
#ifdef TOOLS_MEM
|
||||
mem::increment(s_class().c_str());
|
||||
#endif
|
||||
m_baskets.resize(m_max_baskets,0);
|
||||
fBasketBytes = new uint32[m_max_baskets];
|
||||
fBasketEntry = new uint32[m_max_baskets];
|
||||
fBasketSeek = new seek[m_max_baskets];
|
||||
{for(uint32 i=0;i<m_max_baskets;i++) {
|
||||
m_baskets[i] = 0;
|
||||
fBasketBytes[i] = 0;
|
||||
fBasketEntry[i] = 0;
|
||||
fBasketSeek[i] = 0;
|
||||
}}
|
||||
m_baskets.push_back(new basket(m_tree.dir().file(),
|
||||
m_tree.dir().seek_directory(),
|
||||
m_name,m_title,"TBasket",
|
||||
m_basket_size));
|
||||
m_baskets[m_write_basket] = new basket(m_out,m_byte_swap,a_seek_directory,
|
||||
m_name,m_title,"TBasket",m_basket_size,m_verbose);
|
||||
fBasketEntry[m_write_basket] = (uint32)m_entry_number;
|
||||
}
|
||||
virtual ~branch(){
|
||||
// {for(uint32 i=0;i<=m_write_basket;i++) {
|
||||
// m_out << " " << i << ", " << fBasketEntry[i] << std::endl;
|
||||
// }}
|
||||
|
||||
delete [] fBasketBytes;
|
||||
delete [] fBasketEntry;
|
||||
delete [] fBasketSeek;
|
||||
fBasketBytes = 0;
|
||||
fBasketEntry = 0;
|
||||
fBasketSeek = 0;
|
||||
|
||||
#ifdef TOOLS_MEM
|
||||
mem::decrement(s_class().c_str());
|
||||
#endif
|
||||
@@ -153,37 +175,48 @@ public:
|
||||
protected:
|
||||
branch(const branch& a_from)
|
||||
:ibo(a_from)
|
||||
,m_tree(a_from.m_tree)
|
||||
,m_out(a_from.m_out)
|
||||
,m_seek_directory(a_from.m_seek_directory)
|
||||
{}
|
||||
branch& operator=(const branch&){return *this;}
|
||||
public:
|
||||
uint64 entries() const {return m_entries;}
|
||||
|
||||
uint64 tot_bytes() const {return m_tot_bytes;}
|
||||
void set_tot_bytes(uint64 a_value) {m_tot_bytes = a_value;}
|
||||
|
||||
uint64 zip_bytes() const {return m_zip_bytes;}
|
||||
void set_zip_bytes(uint64 a_value) {m_zip_bytes = a_value;}
|
||||
|
||||
void set_basket_size(uint32 a_size) {m_basket_size = a_size;}
|
||||
uint32 basket_size() const {return m_basket_size;}
|
||||
|
||||
template <class T>
|
||||
leaf<T>* create_leaf(const std::string& a_name,const std::string& a_title){
|
||||
leaf<T>* lf = new leaf<T>(m_out,*this,a_name,a_title);
|
||||
leaf<T>* lf = new leaf<T>(m_out,a_name,a_title);
|
||||
m_leaves.push_back(lf);
|
||||
return lf;
|
||||
}
|
||||
|
||||
leaf_string* create_leaf_string(const std::string& a_name,const std::string& a_title){
|
||||
leaf_string* lf = new leaf_string(m_out,*this,a_name,a_title);
|
||||
leaf_string* lf = new leaf_string(m_out,a_name,a_title);
|
||||
m_leaves.push_back(lf);
|
||||
return lf;
|
||||
}
|
||||
|
||||
const std::vector<base_leaf*>& leaves() const {return m_leaves;}
|
||||
|
||||
bool fill(uint32& a_nbytes) {
|
||||
bool fill(ifile& a_file,uint32& a_nbytes,uint32& a_add_bytes,uint32& a_nout) {
|
||||
a_nbytes = 0;
|
||||
a_add_bytes = 0;
|
||||
a_nout = 0;
|
||||
|
||||
//FIXME if (TestBit(kDoNotProcess)) return 0;
|
||||
|
||||
basket* bk = m_baskets[m_write_basket];
|
||||
if(!bk) {
|
||||
m_out << "tools::wroot::branch::fill :"
|
||||
<< " get_basket failed."
|
||||
<< " m_baskets[m_write_basket] should not be null."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -202,20 +235,24 @@ public:
|
||||
uint32 nbytes = lnew - lold;
|
||||
uint32 nsize = 0;
|
||||
|
||||
uint32 add_bytes = 0;
|
||||
uint32 nout = 0;
|
||||
|
||||
// Should we create a new basket?
|
||||
// Compare expected next size with m_basket_size.
|
||||
if((lnew+2*nsize+nbytes)>=m_basket_size) {
|
||||
uint32 nout;
|
||||
if(!bk->write_on_file(m_write_basket,nout)) {
|
||||
if(!bk->write_on_file(a_file,m_write_basket,nout)) {//it set bk m_seek_key, set a_file.m_END.
|
||||
//Does a a_file.set_END().
|
||||
m_out << "tools::wroot::branch::fill :"
|
||||
<< " basket.write_buffer() failed."
|
||||
<< " basket.write_on_file() failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
fBasketBytes[m_write_basket] = bk->number_of_bytes();
|
||||
//fBasketEntry[m_write_basket] //can't be set here.
|
||||
//fBasketEntry[m_write_basket] = // not done here since we do not know here the first entry.
|
||||
fBasketSeek[m_write_basket] = bk->seek_key();
|
||||
uint32 add_bytes = bk->object_size() + bk->key_length();
|
||||
|
||||
add_bytes = bk->object_size() + bk->key_length();
|
||||
|
||||
delete bk;
|
||||
m_baskets[m_write_basket] = 0;
|
||||
@@ -223,66 +260,204 @@ public:
|
||||
m_tot_bytes += add_bytes;
|
||||
m_zip_bytes += nout;
|
||||
|
||||
m_tree.add_tot_bytes(add_bytes);
|
||||
m_tree.add_zip_bytes(nout);
|
||||
|
||||
bk = new basket(m_tree.dir().file(),m_tree.dir().seek_directory(),
|
||||
m_name,m_title,"TBasket",m_basket_size);
|
||||
|
||||
m_write_basket++;
|
||||
if(!check_alloc_fBasketXxx()) return false;
|
||||
|
||||
if(m_write_basket>=m_baskets.size()) {
|
||||
m_baskets.resize(2*m_write_basket,0);
|
||||
}
|
||||
m_baskets[m_write_basket] = bk;
|
||||
|
||||
if(m_write_basket>=m_max_baskets) {
|
||||
//Increase BasketEntry buffer of a minimum of 10 locations
|
||||
// and a maximum of 50 per cent of current size
|
||||
uint32 newsize = mx<uint32>(10,uint32(1.5*m_max_baskets));
|
||||
if(newsize>=START_BIG_FILE()) {
|
||||
//we are going to have pb with uint32[] indexing.
|
||||
m_out << "tools::wroot::branch::fill :"
|
||||
<< " new size for fBasket[Bytes,Entry,Seek] arrays"
|
||||
<< " is too close of 32 bits limit."
|
||||
<< std::endl;
|
||||
m_out << "tools::wroot::branch::fill :"
|
||||
<< " you have to work with larger basket size."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!realloc<uint32>(fBasketBytes,newsize,m_max_baskets,true)) {
|
||||
m_out << "tools::wroot::branch::fill : realloc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(!realloc<uint32>(fBasketEntry,newsize,m_max_baskets,true)){
|
||||
m_out << "tools::wroot::branch::fill : realloc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(!realloc<seek>(fBasketSeek,newsize,m_max_baskets,true)){
|
||||
m_out << "tools::wroot::branch::fill : realloc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_max_baskets = newsize;
|
||||
}
|
||||
fBasketBytes[m_write_basket] = 0;
|
||||
m_baskets[m_write_basket] = new basket(m_out,m_byte_swap,
|
||||
m_seek_directory,m_name,m_title,"TBasket",m_basket_size,
|
||||
m_verbose);
|
||||
fBasketEntry[m_write_basket] = (uint32)m_entry_number;
|
||||
fBasketSeek[m_write_basket] = 0;
|
||||
}
|
||||
a_nbytes = nbytes;
|
||||
a_add_bytes = add_bytes;
|
||||
a_nout = nout;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// for parallelization : /////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
bool add_basket(ifile& a_file,basket& a_basket,uint32& a_add_bytes,uint32& a_nout) {
|
||||
//done on a (main) ntuple/branch.
|
||||
|
||||
uint32 nout;
|
||||
if(!a_basket.write_on_file(a_file,m_write_basket,nout)) { //a_file is the main file (a true file).
|
||||
//the upper set a_basket.m_seek_key, set a_file.m_END. Does a a_file.set_END().
|
||||
m_out << "tools::wroot::branch::add_basket :"
|
||||
<< " basket.write_on_file() failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
fBasketBytes[m_write_basket] = a_basket.number_of_bytes();
|
||||
fBasketEntry[m_write_basket] = (uint32)m_entry_number;
|
||||
fBasketSeek[m_write_basket] = a_basket.seek_key();
|
||||
|
||||
m_entries += a_basket.nev();
|
||||
m_entry_number += a_basket.nev();
|
||||
|
||||
uint32 add_bytes = a_basket.object_size() + a_basket.key_length();
|
||||
|
||||
delete m_baskets[m_write_basket];
|
||||
m_baskets[m_write_basket] = 0;
|
||||
|
||||
m_write_basket++;
|
||||
if(!check_alloc_fBasketXxx()) return false;
|
||||
|
||||
m_baskets[m_write_basket] = new basket(m_out,m_byte_swap,
|
||||
m_seek_directory,m_name,m_title,"TBasket",m_basket_size,
|
||||
m_verbose);
|
||||
fBasketEntry[m_write_basket] = (uint32)m_entry_number;
|
||||
|
||||
a_add_bytes = add_bytes;
|
||||
a_nout = nout;
|
||||
return true;
|
||||
}
|
||||
|
||||
class iadd_basket {
|
||||
public:
|
||||
virtual ~iadd_basket() {}
|
||||
public:
|
||||
virtual bool add_basket(basket&) = 0;
|
||||
};
|
||||
|
||||
bool pfill(iadd_basket& a_badd) {
|
||||
//done on a pntuple/branch.
|
||||
|
||||
//a_nbytes = 0;
|
||||
//a_add_bytes = 0;
|
||||
//a_nout = 0;
|
||||
|
||||
// this method uses always m_baskets[0].
|
||||
|
||||
basket* bk = m_baskets[m_write_basket];
|
||||
if(!bk) {
|
||||
m_out << "tools::wroot::branch::parallel_fill :"
|
||||
<< " get_basket failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer& buf = bk->datbuf();
|
||||
|
||||
uint32 lold = buf.length();
|
||||
|
||||
bk->update(bk->key_length()+lold);
|
||||
|
||||
//m_entries++; //not used by parallel branches.
|
||||
//m_entry_number++; //idem.
|
||||
|
||||
if(!fill_leaves(buf)) return false;
|
||||
|
||||
uint32 lnew = buf.length();
|
||||
uint32 nbytes = lnew - lold;
|
||||
|
||||
//uint32 add_bytes = 0;
|
||||
//uint32 nout = 0;
|
||||
|
||||
// Should we create a new basket?
|
||||
// Compare expected next size with m_basket_size.
|
||||
if((lnew+nbytes)>=m_basket_size) {
|
||||
if(!a_badd.add_basket(*bk)) {
|
||||
m_out << "tools::wroot::branch::parallel_fill :"
|
||||
<< " main_branch.add_basket() failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
delete bk;
|
||||
bool main_branch_byte_swap = m_byte_swap; //NOTE : it assumes that pntuple/branch and main/branch have same byte_swap.
|
||||
bool main_branch_verbose = m_verbose;
|
||||
m_baskets[m_write_basket] = new basket(m_out,main_branch_byte_swap,
|
||||
m_seek_directory,m_name,m_title,"TBasket",m_basket_size,
|
||||
main_branch_verbose);
|
||||
//a_mutex.unlock();
|
||||
}
|
||||
//a_nbytes = nbytes;
|
||||
//a_add_bytes = add_bytes;
|
||||
//a_nout = nout;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool end_pfill(iadd_basket& a_badd) {
|
||||
//done on a pntuple/branch.
|
||||
|
||||
basket* bk = m_baskets[m_write_basket];
|
||||
if(!bk) {
|
||||
m_out << "tools::wroot::branch::end_pfill :"
|
||||
<< " m_baskets[m_write_basket] should not be null."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!a_badd.add_basket(*bk)) {
|
||||
m_out << "tools::wroot::branch::parallel_fill :"
|
||||
<< " main_branch.add_basket() failed."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
delete bk;
|
||||
m_baskets[m_write_basket] = 0; // no need to recreate a basket since it is end of fill.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
protected:
|
||||
bool check_alloc_fBasketXxx() {
|
||||
if(m_write_basket>=m_max_baskets) {
|
||||
//Increase BasketEntry buffer of a minimum of 10 locations
|
||||
// and a maximum of 50 per cent of current size
|
||||
uint32 newsize = mx<uint32>(10,uint32(1.5*m_max_baskets));
|
||||
if(newsize>=START_BIG_FILE()) {
|
||||
//we are going to have pb with uint32[] indexing.
|
||||
m_out << "tools::wroot::branch::add_basket :"
|
||||
<< " new size for fBasket[Bytes,Entry,Seek] arrays"
|
||||
<< " is too close of 32 bits limit."
|
||||
<< std::endl;
|
||||
m_out << "tools::wroot::branch::add_basket :"
|
||||
<< " you have to work with larger basket size."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_baskets.resize(newsize,0);
|
||||
|
||||
if(!realloc<uint32>(fBasketBytes,newsize,m_max_baskets,true)) {
|
||||
m_out << "tools::wroot::branch::add_basket : realloc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(!realloc<uint32>(fBasketEntry,newsize,m_max_baskets,true)){
|
||||
m_out << "tools::wroot::branch::add_basket : realloc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(!realloc<seek>(fBasketSeek,newsize,m_max_baskets,true)){
|
||||
m_out << "tools::wroot::branch::add_basket : realloc failed." << std::endl;
|
||||
return false;
|
||||
}
|
||||
m_max_baskets = newsize;
|
||||
}
|
||||
|
||||
m_baskets[m_write_basket] = 0;
|
||||
fBasketBytes[m_write_basket] = 0;
|
||||
fBasketEntry[m_write_basket] = 0;
|
||||
fBasketSeek[m_write_basket] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool fill_leaves(buffer& a_buffer) { //virtual for branch_element.
|
||||
tools_vforit(base_leaf*,m_leaves,it) {
|
||||
if(!(*it)->fill_basket(a_buffer)) return false;
|
||||
if(!(*it)->fill_buffer(a_buffer)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
itree& m_tree;
|
||||
std::ostream& m_out;
|
||||
bool m_byte_swap;
|
||||
bool m_verbose;
|
||||
seek m_seek_directory;
|
||||
ObjArray<basket> m_baskets;
|
||||
protected:
|
||||
//Object
|
||||
@@ -294,6 +469,7 @@ protected:
|
||||
bool fAutoDelete;
|
||||
ObjArray<branch> m_branches;
|
||||
ObjArray<base_leaf> m_leaves;
|
||||
uint32 fCompress; // Compression level and algorithm
|
||||
uint32 m_basket_size; // Initial Size of Basket Buffer
|
||||
uint32 m_write_basket; // Last basket number written
|
||||
uint64 m_entry_number; // Current entry number (last one filled in this branch)
|
||||
|
||||
Reference in New Issue
Block a user