diff --git a/Database/APR/RootStorageSvc/CMakeLists.txt b/Database/APR/RootStorageSvc/CMakeLists.txt index 08bd8f90bb1e54fd9aca241b165f2b4abfd84213..31ade4de54d45233f34b1dfeefd7668faed5db55 100644 --- a/Database/APR/RootStorageSvc/CMakeLists.txt +++ b/Database/APR/RootStorageSvc/CMakeLists.txt @@ -10,10 +10,10 @@ atlas_depends_on_subdirs( PRIVATE AtlasTest/TestTools Control/AthContainers Control/AthContainersInterfaces - Control/CxxUtils Control/RootUtils Database/APR/POOLCore Database/APR/StorageSvc + Database/AthenaRoot/RootAuxDynIO Database/PersistentDataModel GaudiKernel ) @@ -28,13 +28,10 @@ atlas_add_library( RootStorageSvc NO_PUBLIC_HEADERS INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} LINK_LIBRARIES ${ROOT_LIBRARIES} RootUtilsPyROOT - PRIVATE_LINK_LIBRARIES TestTools AthContainers CxxUtils RootUtils POOLCore StorageSvc PersistentDataModel GaudiKernel ) + PRIVATE_LINK_LIBRARIES TestTools AthContainers + RootUtils POOLCore StorageSvc RootAuxDynIO + PersistentDataModel GaudiKernel ) -atlas_add_test( RootAuxVectorFactory_test - SOURCES - test/RootAuxVectorFactory_test.cxx - INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} - LINK_LIBRARIES ${ROOT_LIBRARIES} TestTools AthContainers CxxUtils RootUtils RootUtilsPyROOT POOLCore StorageSvc PersistentDataModel GaudiKernel RootStorageSvc ) # Component list generation: atlas_generate_componentslist( RootStorageSvc ) diff --git a/Database/APR/RootStorageSvc/cmt/requirements b/Database/APR/RootStorageSvc/cmt/requirements index 3a669fb0e9c23c7721f01ba16bf1091abfb456a9..70c9751d6cca52783315124a6fbec5f4d19c96e2 100644 --- a/Database/APR/RootStorageSvc/cmt/requirements +++ b/Database/APR/RootStorageSvc/cmt/requirements @@ -10,20 +10,20 @@ use AtlasROOT AtlasROOT-* External private use AthContainersInterfaces AthContainersInterfaces-* Control use AthContainers AthContainers-* Control -use CxxUtils CxxUtils-* Control use RootUtils RootUtils-* Control use PersistentDataModel PersistentDataModel-* Database use POOLCore POOLCore-* Database/APR use StorageSvc StorageSvc-* Database/APR +use RootAuxDynIO RootAuxDynIO-* Database/AthenaRoot use GaudiInterface GaudiInterface-* External apply_pattern pool_plugin_library private -apply_tag ROOTCintexLibs macro_append ROOT_linkopts " -lRIO -lTreePlayer " -use TestTools TestTools-* AtlasTest -apply_pattern UnitTest_run unit_test=RootAuxVectorFactory -macro_append RootAuxVectorFactory_testlinkopts " -lRootStorageSvc" +# no tests in the package any more, but leaving this as an example +# use TestTools TestTools-* AtlasTest +# apply_pattern UnitTest_run unit_test=RootAuxVectorFactory +# macro_append RootAuxVectorFactory_testlinkopts " -lRootStorageSvc" diff --git a/Database/APR/RootStorageSvc/share/RootAuxVectorFactory_test.ref b/Database/APR/RootStorageSvc/share/RootAuxVectorFactory_test.ref deleted file mode 100644 index fadbf1d8531cefc931988be7e19da5fb524c3e74..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/share/RootAuxVectorFactory_test.ref +++ /dev/null @@ -1,4 +0,0 @@ -test1 -test2 -test3 -test4 diff --git a/Database/APR/RootStorageSvc/src/AuxStoreAPR.cpp b/Database/APR/RootStorageSvc/src/AuxStoreAPR.cpp deleted file mode 100644 index 1a43ad6046a4ccc79f8e7415cb09930b16869373..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/src/AuxStoreAPR.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "AuxStoreAPR.h" -#include "RootAuxVectorFactory.h" -#include "AthContainers/tools/error.h" - -#include "AthContainers/AuxTypeRegistry.h" -#include "AthContainers/exceptions.h" -#include "AthContainersInterfaces/AuxDataOption.h" -#include "RootUtils/Type.h" - -#include "TBranch.h" -#include "TLeaf.h" -#include "TClass.h" -#include "TClassTable.h" -#include "TClassEdit.h" -#include "TVirtualCollectionProxy.h" -#include "TROOT.h" - -#include <iostream> - -using namespace pool; -using namespace std; - - -namespace { - - -const std::type_info* dataTypeToTypeInfo (EDataType type, std::string& typeName) -{ - RootUtils::Type typ (type); - typeName = typ.getTypeName(); - return typ.getTypeInfo(); -} - - -/** - * @brief Given a branch, return the aux data type for that branch. - * @param br The branch for which we want to get the type. - * @param standalone Is this for a standalone object? - * @param[out] elementTypeName Name of the type for one aux data element. - * Same as branchTypeName if @c standalone is true. - * @param[out] branchTypeName Name of the type for this branch. - * - * If standalone is true, then we return the type of the branch - * directly. Otherwise, the branch should be a STL vector; - * we return the type of the vector's payload. - * - * Returns 0 on failure. - */ -const std::type_info* getElementType (TBranch* br, - bool standalone, - std::string& elementTypeName, - std::string& branchTypeName) -{ - TClass* expectedClass = 0; - EDataType expectedType = kOther_t; - if (br->GetExpectedType (expectedClass, expectedType) != 0) { - return 0; - } - - if (standalone) { - if (expectedClass) { - elementTypeName = expectedClass->GetName(); - branchTypeName = elementTypeName; - return expectedClass->GetTypeInfo(); - } - const std::type_info* ret = dataTypeToTypeInfo (expectedType, - elementTypeName); - branchTypeName = elementTypeName; - return ret; - } - - // Not standalone; branch should be a vector. - if (!expectedClass) return 0; - - branchTypeName = expectedClass->GetName(); - if (strncmp (expectedClass->GetName(), "vector<", 7) == 0) { - TVirtualCollectionProxy* prox = expectedClass->GetCollectionProxy(); - if (!prox) return 0; - if (prox->GetValueClass()) { - elementTypeName = prox->GetValueClass()->GetName(); - return prox->GetValueClass()->GetTypeInfo(); - } - return dataTypeToTypeInfo (prox->GetType(), elementTypeName); - } - else if (strncmp (expectedClass->GetName(), "SG::PackedContainer<", 20) == 0){ - TClassEdit::TSplitType split (expectedClass->GetName()); - if (split.fElements.size() > 1) { - elementTypeName = split.fElements[1]; - RootUtils::Type typ (elementTypeName); - return typ.getTypeInfo(); - } - } - return 0; -} - - -// Convert from class name to TClass; try to avoid autoparsing. -TClass* getClassIfDictionaryExists (const std::string& cname) -{ -#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0) - return TClass::GetClass (cname.c_str()); -#else - if (TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname.c_str())) { - if (cl->IsLoaded() && cl->HasDictionary()) return cl; - return nullptr; - } - - if (gInterpreter->GetClassSharedLibs (cname.c_str())) { - TClass* cl = TClass::GetClass (cname.c_str()); - if (cl->HasDictionary()) - return cl; - } - return nullptr; -#endif -} - - -} // Anonymous namespace - - -AuxStoreAPR::AuxStoreAPR(RootTreeContainer &container, long long entry, bool standalone) - : SG::AuxStoreInternal (standalone), - m_entry(entry), m_container(container) -{ - SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance(); - for( const auto& attr2branch: m_container.m_auxBranches ) { - const string& attr = attr2branch.first; - std::string elemen_type_name; - std::string branch_type_name; - const std::type_info* ti = getElementType(attr2branch.second, - standalone, - elemen_type_name, - branch_type_name); - SG::auxid_t auxid = r.findAuxID(attr); - if( ti ) { - if (auxid == SG::null_auxid) { - auxid = r.getAuxID(*ti, attr); - } else { - const std::type_info* reg_ti = r.getType(auxid); - if( ti != reg_ti && strcmp(ti->name(), reg_ti->name()) != 0 ) { - DbPrint log(container.getName()); - log << DbPrintLvl::Debug << "reading attribute " << attr << " (id=" << auxid << - " typename=" << reg_ti->name() << ") has different type than the branch " - << branch_type_name << DbPrint::endmsg; - m_container.findAuxBranch(auxid); // call this to init_auxBranchMap[auxid] - m_container.m_auxBranchMap[auxid].aux_type_different = true; - } - } - - if (auxid == SG::null_auxid) { - std::string fac_class_name = "SG::AuxTypeVectorFactory<" + - elemen_type_name; - if (fac_class_name[fac_class_name.size()-1] == '>') - fac_class_name += ' '; - fac_class_name += '>'; - TClass* fac_class = getClassIfDictionaryExists (fac_class_name); - if (fac_class) - { - TClass* base_class = getClassIfDictionaryExists ("SG::IAuxTypeVectorFactory"); - if (base_class) { - int offs = fac_class->GetBaseClassOffset (base_class); - if (offs >= 0) { - void* fac_vp = fac_class->New(); - if (fac_vp) { - SG::IAuxTypeVectorFactory* fac = reinterpret_cast<SG::IAuxTypeVectorFactory*> (reinterpret_cast<unsigned long>(fac_vp) + offs); - r.addFactory (*ti, fac); - auxid = r.getAuxID(*ti, attr); - } - } - } - } - } - - if (auxid == SG::null_auxid) { - std::string vec_name = branch_type_name; - if (standalone) { - vec_name = "std::vector<" + branch_type_name; - if (vec_name[vec_name.size()-1] == '>') - vec_name += " "; - vec_name += ">"; - } - TClass* vec_class = TClass::GetClass (vec_name.c_str()); - - if (vec_class) { - SG::IAuxTypeVectorFactory* fac = new RootAuxVectorFactory (vec_class); - r.addFactory (*ti, fac); - auxid = r.getAuxID(*ti, attr); - } - } - - } - - // add AuxID to the list - // May still be null if we don't have a dictionary for the branch. - if (auxid != SG::null_auxid) - addAuxID (auxid); - } - - lock(); -} - - -const void* AuxStoreAPR::getData(SG::auxid_t auxid) const -{ - guard_t guard (m_mutex); - // lock - const void* ret = SG::AuxStoreInternal::getData (auxid); - if (!ret) { - const_cast<AuxStoreAPR*>(this)->readData(auxid); - ret = SG::AuxStoreInternal::getData (auxid); - } - return ret; -} - - -const void* AuxStoreAPR::getIOData(SG::auxid_t auxid) const -{ - guard_t guard (m_mutex); - const void* ret = SG::AuxStoreInternal::getIODataInternal (auxid, true); - if (!ret) { - const_cast<AuxStoreAPR*>(this)->readData(auxid); - ret = SG::AuxStoreInternal::getIOData (auxid); - } - return ret; -} - - -bool AuxStoreAPR::readData(SG::auxid_t auxid) -{ - //cout << "AuxStoreAPR::getData() id=" << auxid << ", name=" - // << reg.getName(auxid) << ", container=" << m_container.m_branchName << endl; - - TBranch* branch = m_container.findAuxBranch(auxid); - // check if there is a branch in the file - if( !branch ) return false; - // cout << " Branch: name=" << branch->GetName() << ", class name=" << branch->GetClassName() << endl; - - TClass* cl = 0; - EDataType typ; - if( branch->GetExpectedType(cl, typ) ) { - ATHCONTAINERS_ERROR("AuxStoreAPR::getData", string("Error getting branch type for ") + branch->GetName() ); - return false; - } - - // Make a 1-element vector. - SG::AuxStoreInternal::getDataInternal(auxid, 1, 1, true); - if (!standalone()) { - if (cl && strncmp (cl->GetName(), "SG::PackedContainer<", 20) == 0) - setOption (auxid, SG::AuxDataOption ("nbits", 32)); - } - - // get memory location where to write data from the branch entry - void * vector = const_cast<void*>(SG::AuxStoreInternal::getIOData (auxid)); // xxx - void * data = &vector; - if (standalone() && !cl) { - // raeding fundamental type, ROOT does it a bit differently - data = vector; - } - - // read branch - if( m_container.m_auxBranchMap[auxid].aux_type_different ) { - // reading through the TTree - allows for schema evolution - if( m_container.readAuxBranch(*branch, data, getIOType(auxid), m_entry).isSuccess() ) - return true; - } else { - if( m_container.readAuxBranch(*branch, data, m_entry).isSuccess() ) - return true; - } - - ATHCONTAINERS_ERROR("AuxStoreAPR::getData", string("Error reading branch ") + branch->GetName() ); - return false; -} - - -/** - * @brief Return the data vector for one aux data decoration item. - * @param auxid The identifier of the desired aux data item. - * @param size The current size of the container (in case the data item - * does not already exist). - * @param capacity The current capacity of the container (in case - * the data item does not already exist). - * - * Each aux data item is stored as a vector, with one entry - * per entry in the owning container. This returns a pointer - * to the start of the vector. - * - * The base class implementation works except for the case where we have - * not yet created a vector for an item in the root file. We need to - * detect that case and raise an exception. - */ -void* -AuxStoreAPR::getDecoration (SG::auxid_t auxid, size_t size, size_t capacity) -{ - guard_t guard (m_mutex); - if (SG::AuxStoreInternal::getIODataInternal (auxid, true) == 0 && - SG::AuxStoreInternal::getAuxIDs().count (auxid) > 0) - { - throw SG::ExcStoreLocked (auxid); - } - return SG::AuxStoreInternal::getDecoration (auxid, size, capacity); -} - - diff --git a/Database/APR/RootStorageSvc/src/AuxStoreAPR.h b/Database/APR/RootStorageSvc/src/AuxStoreAPR.h deleted file mode 100644 index 1ef79f5aa0cee67d6b8b1f20b590b871dd85f783..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/src/AuxStoreAPR.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef ROOTSTORAGESVC_AUXSTOREAPR -#define ROOTSTORAGESVC_AUXSTOREAPR - -#include "AthContainers/AuxStoreInternal.h" -#include "RootTreeContainer.h" - -#include <stdexcept> -#include "AthContainersInterfaces/IAuxTypeVector.h" - -#include "TClass.h" - -namespace pool { - - class AuxStoreAPR : public SG::AuxStoreInternal - { - public: - AuxStoreAPR(RootTreeContainer &container, long long entry, bool standalone=false); - virtual ~AuxStoreAPR() {} - - /// implementation of the IAuxStore interface - virtual const void* getData(SG::auxid_t auxid) const; - virtual void* getData(SG::auxid_t auxid, size_t size, size_t capacity); - - /// implementation of the IAuxStoreIO interface - virtual const void* getIOData(SG::auxid_t auxid) const; - - - /** - * @brief Return the data vector for one aux data decoration item. - * @param auxid The identifier of the desired aux data item. - * @param size The current size of the container (in case the data item - * does not already exist). - * @param capacity The current capacity of the container (in case - * the data item does not already exist). - */ - void* getDecoration (SG::auxid_t auxid, size_t size, size_t capacity); - - - protected: - /// read data from ROOT and store it in m_vecs. Returns False on error - bool readData(SG::auxid_t auxid); - - protected: - long long m_entry; - RootTreeContainer &m_container; - - - private: - /// Mutex used to synchronize modifications to the cache vector. - typedef AthContainers_detail::mutex mutex_t; - typedef AthContainers_detail::lock_guard<mutex_t> guard_t; - mutable mutex_t m_mutex; - }; - - - - inline - void* AuxStoreAPR::getData(SG::auxid_t auxid, size_t /*size*/, size_t /*capacity*/) - { - // MN: how do we add new attributes to this store? A:for now we don't - return const_cast<void*>(getData(auxid)); - } - -} - -#endif - diff --git a/Database/APR/RootStorageSvc/src/RootAuxVectorFactory.cpp b/Database/APR/RootStorageSvc/src/RootAuxVectorFactory.cpp deleted file mode 100644 index dd90548e38e8b81b18969826d7a7825fcd4eb76e..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/src/RootAuxVectorFactory.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// $Id$ -/** - * @file RootStorageSvc/src/RootAuxVectorFactory.cpp - * @author scott snyder <snyder@bnl.gov> - * @date May, 2014 - * @brief Dynamic implementation of @c IAuxVectorFactory, - * relying on root vector proxy. - */ - - -#include "RootAuxVectorFactory.h" -#include "AthContainers/tools/error.h" -#include "TClass.h" -#include "TVirtualCollectionProxy.h" -#include "TROOT.h" -#include <iostream> -#include <stdexcept> - - -namespace pool { - - -/** - * @brief Find the vector type associated with @c CL by looking - * up the @c vector_type typedef. - * @param cl The class for which to find the associated vector type. - * - * Given type CL, looks for a typedef CL::vector_type and returns the TClass - * for that if found. Works for, eg, SG::PackedContainer. - */ -TClass* lookupVectorType (TClass *cl) -{ - std::string tname = cl->GetName(); - tname += "::vector_type"; - TDataType* typ = gROOT->GetType (tname.c_str()); - if (typ) - return TClass::GetClass (typ->GetFullTypeName()); - return nullptr; -} - - -/** - * @brief Constructor. Makes a new vector. - * @param factory The factory object for this type. - * @param size Initial size of the new vector. - * @param capacity Initial capacity of the new vector. - */ -RootAuxVector::RootAuxVector (const RootAuxVectorFactory* factory, - size_t size, size_t /*capacity*/) - : m_factory (factory) -{ - TClass* vecClass = factory->vecClass(); - m_proxy = vecClass->GetCollectionProxy(); - m_obj = factory->objClass()->New (); - m_vec = reinterpret_cast<char*> (m_obj) + factory->offset(); - this->resize (size); -} - - -/** - * @brief Copy constructor. - * @param other The vector to copy. - */ -RootAuxVector::RootAuxVector (const RootAuxVector& other) - : m_factory (other.m_factory), - m_proxy (other.m_proxy) -{ - m_obj = m_factory->objClass()->New (); - m_vec = reinterpret_cast<char*> (m_obj) + m_factory->offset(); - size_t sz = other.size(); - this->resize (sz); - - if (sz > 0) { - const RootUtils::Type& rootType = m_factory->rootType(); - - const void* otherPtr = 0; - { - TVirtualCollectionProxy::TPushPop bind (m_proxy, other.m_vec); - otherPtr = m_proxy->At(0); - } - - rootType.copyRange (this->toPtr(), otherPtr, sz); - } -} - - -/** - * @brief Destructor. - * - * This will free the vector data. - */ -RootAuxVector::~RootAuxVector() -{ - m_factory->objClass()->Destructor (m_obj); -} - - -/** - * @brief Make a copy of this vector. - */ -SG::IAuxTypeVector* RootAuxVector::clone() const -{ - return new RootAuxVector (*this); -} - - -/** - * @brief Return a pointer to the start of the vector's data. - */ -void* RootAuxVector::toPtr () -{ - TVirtualCollectionProxy::TPushPop bind (m_proxy, m_vec); - if (m_proxy->Size() == 0) - return 0; - return m_proxy->At(0); -} - - -/** - * @brief Return a pointer to the overall object. - */ -void* RootAuxVector::toVector () -{ - return m_obj; -} - - -/** - * @brief Return the size of the vector. - */ -size_t RootAuxVector::size() const -{ - TVirtualCollectionProxy::TPushPop bind (m_proxy, m_vec); - return m_proxy->Size(); -} - - -/** - * @brief Change the size of the vector. - * @param sz The new vector size. - */ -void RootAuxVector::resize (size_t sz) -{ - TVirtualCollectionProxy::TPushPop bind (m_proxy, m_vec); - m_proxy->Allocate(sz, false); -} - - -/** - * @brief Change the capacity of the vector. - * @param sz The new vector capacity. - */ -void RootAuxVector::reserve (size_t /*sz*/) -{ -} - - -/** - * @brief Shift the elements of the vector. - * @param pos The starting index for the shift. - * @param offs The (signed) amount of the shift. - * - * This operation shifts the elements in the vectors for all - * aux data items, to implement an insertion or deletion. - * @c offs may be either positive or negative. - * - * If @c offs is positive, then the container is growing. - * The container size should be increased by @c offs, - * the element at @c pos moved to @c pos + @c offs, - * and similarly for following elements. - * The elements between @c pos and @c pos + @c offs should - * be default-initialized. - * - * If @c offs is negative, then the container is shrinking. - * The element at @c pos should be moved to @c pos + @c offs, - * and similarly for following elements. - * The container should then be shrunk by @c -offs elements - * (running destructors as appropriate). - */ -void RootAuxVector::shift (size_t pos, ptrdiff_t offs) -{ - TVirtualCollectionProxy::TPushPop bind (m_proxy, m_vec); - size_t eltsz = m_proxy->GetIncrement(); - - const RootUtils::Type& rootType = m_factory->rootType(); - - if (offs < 0) { - if (-offs > static_cast<ptrdiff_t>(pos)) offs = -pos; - char* beg = reinterpret_cast<char*>(m_proxy->At(0)); - rootType.copyRange (beg + eltsz*(pos+offs), - beg + eltsz*pos, - m_proxy->Size() - pos); - m_proxy->Allocate (m_proxy->Size() + offs, false); - } - else if (offs > 0) { - size_t oldsz = m_proxy->Size(); - m_proxy->Allocate (oldsz + offs, false); - char* beg = reinterpret_cast<char*>(m_proxy->At(0)); - rootType.copyRange (beg + eltsz*(pos+offs), - beg + eltsz*pos, - m_proxy->Size() - pos - offs); - rootType.clearRange (beg + eltsz*pos, offs); - } -} - - -/** - * @brief Return the type of the complete object to be saved. - * - * For example, if the object is a @c std::vector, then we return - * the @c type_info of the vector. But if we're holding - * a @c PackedContainer, then we return the @c type_info of the - * @c PackedContainer. - * - * Can return null if the operation is not supported. In that case, - * I/O will use the type found from the variable registry. - */ -const std::type_info* RootAuxVector::objType() const -{ - return m_factory->objClass()->GetTypeInfo(); -} - - -//================================================================== - - -/** - * @brief Constructor. - * @param vecClass The @c TClass for the vector object. - */ -RootAuxVectorFactory::RootAuxVectorFactory (TClass* objClass) - : m_objClass (objClass), - m_vecClass (objClass), - m_offset (0) -{ - TVirtualCollectionProxy* proxy = m_vecClass->GetCollectionProxy(); - - if (!proxy) { - TClass* vecClass = lookupVectorType (objClass); - if (vecClass) { - m_vecClass = vecClass; - Int_t offs = objClass->GetBaseClassOffset (vecClass); - if (offs >= 0) { - m_offset = offs; - proxy = vecClass->GetCollectionProxy(); - } - else { - ATHCONTAINERS_ERROR("RootAuxVectorFactory::RootAuxVectorFactory", - std::string("Can't find vector base class in ") + - objClass->GetName()); - } - } - } - - if (!proxy) { - std::string err = "Can't find collection proxy for "; - err += m_vecClass->GetName(); - throw std::runtime_error (err.c_str()); - } - - if (m_vecClass->GetTypeInfo() == 0) { - ATHCONTAINERS_ERROR("RootAuxVectorFactory::RootAuxVectorFactory", - std::string("No type_info available for class ") + - m_vecClass->GetName() + - std::string(". There is probably a missing dictionary. We will likely crash further on.")); - } - - TClass* eltClass = proxy->GetValueClass(); - if (eltClass) - m_type.init (eltClass); - else - m_type.init (proxy->GetType()); -} - - -/** - * @brief Destructor. - */ -RootAuxVectorFactory::~RootAuxVectorFactory() -{ -} - - -/** - * @brief Create a vector object of this type. - * @param size Initial size of the new vector. - * @param capacity Initial capacity of the new vector. - */ -SG::IAuxTypeVector* -RootAuxVectorFactory::create (size_t size, size_t capacity) const -{ - return new RootAuxVector (this, size, capacity); -} - - -/** - * @brief Copy an element between vectors. - * @param dst Pointer to the start of the destination vector's data. - * @param dst_index Index of destination element in the vector. - * @param src Pointer to the start of the source vector's data. - * @param src_index Index of source element in the vector. - * - * @c dst and @ src can be either the same or different. - */ -void RootAuxVectorFactory::copy (void* dst, size_t dst_index, - const void* src, size_t src_index) const -{ - m_type.assign (dst, dst_index, src, src_index); -} - - -/** - * @brief Swap an element between vectors. - * @param a Pointer to the start of the first vector's data. - * @param aindex Index of the element in the first vector. - * @param b Pointer to the start of the second vector's data. - * @param bindex Index of the element in the second vector. - * - * @c a and @ b can be either the same or different. - */ -void RootAuxVectorFactory::swap (void* a, size_t aindex, - void* b, size_t bindex) const -{ - m_type.swap (a, aindex, b, bindex); -} - - -/** - * @brief Clear an element within a vector (static method). - * @param dst Pointer to the start of the vector's data. - * @param dst_index Index of the element in the vector. - */ -void RootAuxVectorFactory::clear (void* dst, size_t dst_index) const -{ - m_type.clear (dst, dst_index); -} - - -/** - * @brief Return the size of an element of this vector type. - */ -size_t RootAuxVectorFactory::getEltSize() const -{ - return m_type.getSize(); -} - - -/** - * @brief Return the @c type_info of the overall object. - */ -const std::type_info* RootAuxVectorFactory::tiVec() const -{ - return m_objClass->GetTypeInfo(); -} - - -/** - * @brief True if the vectors created by this factory work by dynamic - * emulation (via @c TVirtualCollectionProxy or similar); false - * if the std::vector code is used directly. - */ -bool RootAuxVectorFactory::isDynamic() const -{ - return true; -} - - -} // namespace pool diff --git a/Database/APR/RootStorageSvc/src/RootAuxVectorFactory.h b/Database/APR/RootStorageSvc/src/RootAuxVectorFactory.h deleted file mode 100644 index d752cd8baeda45a08896cd265d2549cb8dd3cb3b..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/src/RootAuxVectorFactory.h +++ /dev/null @@ -1,314 +0,0 @@ -// This file's extension implies that it's C, but it's really -*- C++ -*-. - -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// $Id$ -/** - * @file RootAuxVectorFactory.h - * @author scott snyder <snyder@bnl.gov> - * @date May, 2014 - * @brief Dynamic implementation of @c IAuxVectorFactory, - * relying on root's vector proxy. - */ - - -#ifndef ROOTSTORAGESCVC_ROOTAUXVECTORFACTORY_H -#define ROOTSTORAGESCVC_ROOTAUXVECTORFACTORY_H - - -#include "AthContainersInterfaces/IAuxTypeVectorFactory.h" -#include "AthContainersInterfaces/IAuxTypeVector.h" -#include "RootUtils/Type.h" - - -class TClass; -class TVirtualCollectionProxy; - - -namespace pool { - - -class RootAuxVectorFactory; - - -/** - * @brief Dynamic implementation of @c IAuxTypeVector, - * relying on root vector proxy. - * - * This is used for the case when we need to manipulate an aux data vector - * present in an input data file but we have neither a proper template - * instantiation for the factory (because the variable was never explicitly - * referenced), nor can we find a dictionary entry for the factory.j - * - * This implementation works by relying entirely on the root - * dictionary information. - */ -class RootAuxVector - : public SG::IAuxTypeVector -{ -public: - /** - * @brief Constructor. Makes a new vector. - * @param factory The factory object for this type. - * @param size Initial size of the new vector. - * @param capacity Initial capacity of the new vector. - */ - RootAuxVector (const RootAuxVectorFactory* factory, - size_t size, - size_t capacity); - - - /** - * @brief Copy constructor. - * @param other The vector to copy. - */ - RootAuxVector (const RootAuxVector& other); - - - // Disallow assignment. - RootAuxVector& operator= (const RootAuxVector&) = delete; - - - /** - * @brief Destructor. - * - * This will free the vector data. - */ - virtual ~RootAuxVector() override; - - - /** - * @brief Make a copy of this vector. - */ - virtual SG::IAuxTypeVector* clone() const override; - - - /** - * @brief Return a pointer to the start of the vector's data. - */ - virtual void* toPtr() override; - - - /** - * @brief Return a pointer to the overall object. - */ - virtual void* toVector() override; - - - - /** - * @brief Return the size of the vector. - */ - virtual size_t size() const override; - - - /** - * @brief Change the size of the vector. - * @param sz The new vector size. - */ - virtual void resize (size_t sz) override; - - - /** - * @brief Change the capacity of the vector. - * @param sz The new vector capacity. - */ - virtual void reserve (size_t sz) override; - - - /** - * @brief Shift the elements of the vector. - * @param pos The starting index for the shift. - * @param offs The (signed) amount of the shift. - * - * This operation shifts the elements in the vectors for all - * aux data items, to implement an insertion or deletion. - * @c offs may be either positive or negative. - * - * If @c offs is positive, then the container is growing. - * The container size should be increased by @c offs, - * the element at @c pos moved to @c pos + @c offs, - * and similarly for following elements. - * The elements between @c pos and @c pos + @c offs should - * be default-initialized. - * - * If @c offs is negative, then the container is shrinking. - * The element at @c pos should be moved to @c pos + @c offs, - * and similarly for following elements. - * The container should then be shrunk by @c -offs elements - * (running destructors as appropriate). - */ - virtual void shift (size_t pos, ptrdiff_t offs) override; - - - /** - * @brief Return the type of the complete object to be saved. - * - * For example, if the object is a @c std::vector, then we return - * the @c type_info of the vector. But if we're holding - * a @c PackedContainer, then we return the @c type_info of the - * @c PackedContainer. - * - * Can return null if the operation is not supported. In that case, - * I/O will use the type found from the variable registry. - */ - virtual const std::type_info* objType() const override; - - -private: - /// Pointer back to the factory class for this type. - const RootAuxVectorFactory* m_factory; - - /// The collection proxy for the vector. - TVirtualCollectionProxy* m_proxy; - - /// Pointer to the overall object itself. - void* m_obj; - - /// Pointer to the vector object itself. - void* m_vec; -}; - - -/** - * @brief Dynamic implementation of @c IAuxVectorFactory, - * relying on root's vector proxy. - * - * This is used for the case when we need to manipulate an aux data vector - * present in an input data file but we have neither a proper template - * instantiation for the factory (because the variable was never explicitly - * referenced), nor can we find a dictionary entry for the factory.j - * - * This implementation works by relying entirely on the root - * dictionary information. - * - * We may either be dealing directly with an STL vector class, or with - * embedded in another class (as for PackedContainer). Here, @a vecClass - * is the class of the STL vector and @a objClass is the overall object - * class. In the case of a direct STL vector, these are identical. - */ -class RootAuxVectorFactory - : public SG::IAuxTypeVectorFactory -{ -public: - /** - * @brief Constructor. - * @param vecClass The @c TClass for the vector object. - */ - RootAuxVectorFactory (TClass* objClass); - - - /** - * @brief Destructor. - */ - virtual ~RootAuxVectorFactory() override; - - - /** - * @brief Return the ROOT type wrapper. - */ - const RootUtils::Type& rootType() const { return m_type; } - - - /** - * @brief Return the @c TClass for the overall object. - */ - TClass* objClass() const { return m_objClass; } - - - /** - * @brief Return the @c TClass for the @c std::vector. - */ - TClass* vecClass() const { return m_vecClass; } - - - /** - * @brief Return the offset of the vector within the object. - */ - size_t offset() const { return m_offset; } - - - /** - * @brief Create a vector object of this type. - * @param size Initial size of the new vector. - * @param capacity Initial capacity of the new vector. - */ - virtual SG::IAuxTypeVector* create (size_t size, size_t capacity) const - override; - - - /** - * @brief Copy an element between vectors. - * @param dst Pointer to the start of the destination vector's data. - * @param dst_index Index of destination element in the vector. - * @param src Pointer to the start of the source vector's data. - * @param src_index Index of source element in the vector. - * - * @c dst and @ src can be either the same or different. - */ - virtual void copy (void* dst, size_t dst_index, - const void* src, size_t src_index) const override; - - - /** - * @brief Swap an element between vectors. - * @param a Pointer to the start of the first vector's data. - * @param aindex Index of the element in the first vector. - * @param b Pointer to the start of the second vector's data. - * @param bindex Index of the element in the second vector. - * - * @c a and @ b can be either the same or different. - */ - virtual void swap (void* a, size_t aindex, - void* b, size_t bindex) const override; - - - /** - * @brief Clear an element within a vector (static method). - * @param dst Pointer to the start of the vector's data. - * @param dst_index Index of the element in the vector. - */ - virtual void clear (void* dst, size_t dst_index) const override; - - - /** - * @brief Return the size of an element of this vector type. - */ - virtual size_t getEltSize() const override; - - - /** - * @brief Return the @c type_info of the overall object. - */ - virtual const std::type_info* tiVec() const override; - - - /** - * @brief True if the vectors created by this factory work by dynamic - * emulation (via @c TVirtualCollectionProxy or similar); false - * if the std::vector code is used directly. - */ - virtual bool isDynamic() const override; - - -private: - /// The @c TClass for the overall object. - TClass* m_objClass; - - /// The @c TClass for the std::vector. - TClass* m_vecClass; - - /// Offset of the STL vector within the overall object. - size_t m_offset; - - /// Wrapper for the ROOT type of the element. - RootUtils::Type m_type; -}; - - -} // namespace pool - - -#endif // not ROOTSTORAGESCVC_ROOTAUXVECTORFACTORY_H diff --git a/Database/APR/RootStorageSvc/src/RootDatabase.cpp b/Database/APR/RootStorageSvc/src/RootDatabase.cpp index 71b9907f844f7fa8428415c5c330fdf6064a47ce..971f9b14a256aa3bdcf0b344245b726b40d86cc2 100644 --- a/Database/APR/RootStorageSvc/src/RootDatabase.cpp +++ b/Database/APR/RootStorageSvc/src/RootDatabase.cpp @@ -49,7 +49,7 @@ RootDatabase::RootDatabase(IOODatabase* idb) m_defBufferSize(16*1024), m_defWritePolicy(TObject::kOverwrite), // On write create new versions m_branchOffsetTabLen(0), - m_defTreeCacheLearnEvents(5), + m_defTreeCacheLearnEvents(100), m_fileMgr(0) { m_version = "1.1"; @@ -238,7 +238,7 @@ DbStatus RootDatabase::open(const DbDomain& domH,const std::string& nam,DbAccess << DbPrint::endmsg; } if ( m_file ) { - log << DbPrintLvl::Always << fname << " File version:" << m_file->GetVersion() << DbPrint::endmsg; + log << DbPrintLvl::Info << fname << " File version:" << m_file->GetVersion() << DbPrint::endmsg; if ( !m_file->IsOpen() ) { log << DbPrintLvl::Error << "Failed to open file:" << nam << DbPrint::endmsg; deletePtr(m_file); @@ -599,17 +599,26 @@ DbStatus RootDatabase::setOption(const DbOption& opt) { } return sc; } - else if( !strcasecmp(n+5,"AUTO_FLUSH") ) { + else if ( !strcasecmp(n+5,"AUTO_FLUSH") ) { return setAutoFlush(opt); } else if ( !strcasecmp(n+5,"CACHE_LEARN_EVENTS") ) { - DbStatus s = opt._getValue(m_defTreeCacheLearnEvents); - if( s.isSuccess() ) { - TTreeCache::SetLearnEntries(m_defTreeCacheLearnEvents); - DbPrint log("RootDatabase.setOption"); - log << DbPrintLvl::Debug << n << " = " << m_defTreeCacheLearnEvents << DbPrint::endmsg; - } - return s; + DbStatus s = opt._getValue(m_defTreeCacheLearnEvents); + if( s.isSuccess() ) { + DbPrint log("RootDatabase.setOption"); + if ( m_file->GetListOfKeys()->Contains("CollectionTree") ) { + TTree *tree = (TTree*)m_file->Get("CollectionTree"); + if (tree != 0 && tree->GetAutoFlush() > 0) { + if (m_defTreeCacheLearnEvents < tree->GetAutoFlush()) { + log << DbPrintLvl::Info << n << ": Overwriting LearnEvents with CollectionTree AutoFlush" << DbPrint::endmsg; + m_defTreeCacheLearnEvents = tree->GetAutoFlush(); + } + } + } + TTreeCache::SetLearnEntries(m_defTreeCacheLearnEvents); + log << DbPrintLvl::Debug << n << " = " << m_defTreeCacheLearnEvents << DbPrint::endmsg; + } + return s; } else if ( !strcasecmp(n+5,"CACHE") ) { DbPrint log("RootDatabase.setOption"); @@ -619,10 +628,6 @@ DbStatus RootDatabase::setOption(const DbOption& opt) { int cacheSize = 0; opt._getValue(cacheSize); - if (cacheSize == 0) { - log << DbPrintLvl::Error << "Must set cache size != 0 to start TREE_CACHE " << DbPrint::endmsg; - return Error; - } if (!opt.option().size()) { log << DbPrintLvl::Error << "Must set option to tree name to start TREE_CACHE " << DbPrint::endmsg; return Error; @@ -643,7 +648,7 @@ DbStatus RootDatabase::setOption(const DbOption& opt) { log << DbPrintLvl::Debug << "Using Tree cache. Size: " << cacheSize << " Nevents to learn with: " << m_defTreeCacheLearnEvents << DbPrint::endmsg; } - else { + else if (cacheSize != 0) { log << DbPrintLvl::Error << "Could not get cache " << DbPrint::endmsg; return Error; } diff --git a/Database/APR/RootStorageSvc/src/RootTreeContainer.cpp b/Database/APR/RootStorageSvc/src/RootTreeContainer.cpp index ef368b87962769c526554ade24971f49240762bd..4a93f351a690899585be6889905595b11f9341f7 100755 --- a/Database/APR/RootStorageSvc/src/RootTreeContainer.cpp +++ b/Database/APR/RootStorageSvc/src/RootTreeContainer.cpp @@ -45,9 +45,10 @@ #include "AthContainersInterfaces/IAuxStoreHolder.h" #include "AthContainers/AuxTypeRegistry.h" #include "AthContainers/normalizedTypeinfoName.h" -#include "AuxStoreAPR.h" +#include "RootAuxDynIO/RootAuxDynIO.h" using namespace pool; +using namespace std; namespace { @@ -122,17 +123,11 @@ void fixupPackedConversion (TBranch* br) } // anonymous namespace -namespace SG { - /// Common post-fix for the names of auxiliary containers in StoreGate - static const std::string AUX_POSTFIX = "Aux."; - static const std::string AUXDYN_POSTFIX = "Dyn."; -} - -static UCharDbArray s_char_Blob; +static UCharDbArrayAthena s_char_Blob; static IntDbArray s_int_Blob; -#include <iostream> -using namespace std; +//#include <iostream> +//using namespace std; RootTreeContainer::RootTreeContainer(IOODatabase* idb) @@ -245,7 +240,7 @@ DbStatus RootTreeContainer::writeObject(TransactionStack::value_type& ent) { num_bytes += bytes_out; } } - store->selectAux( std::set<string>() ); + store->selectAux( std::set<std::string>() ); } dsc.rows_written++; break; @@ -463,14 +458,9 @@ RootTreeContainer::loadObject(DataCallBack* call, Token::OID_t& oid, DbAccessMod case DbColumn::POINTER: // for AUX store objects with the right interface supply a special store object // that will read branches on demand - if( dsc.aux_storehdl_IFoffset >= 0 ) { - // cout << " *** SG::IAuxStoreHolder detected in " << dsc.clazz->GetName() << ", entry# " << evt_id << endl; - auto store_holder = reinterpret_cast<SG::IAuxStoreHolder*>( *(char**)dsc.object + dsc.aux_storehdl_IFoffset ); - //store_holder->setStore( new AuxStoreAPR(*this, evt_id, dsc.clazz->GetBaseClass("xAOD::AuxInfoBase")!=0) ); - bool standalone( store_holder->getStoreType()==SG::IAuxStoreHolder::AST_ObjectStore ); - // create an AUX dynamic store object for reading attribute branches on demand - // and pass it to the controlling static AUX store object that was just read - store_holder->setStore( new AuxStoreAPR(*this, evt_id, standalone) ); + if( dsc.aux_reader ) { + // cout << " *** AuxDyn reader detected in " << dsc.clazz->GetName() << ", entry# " << evt_id << endl; + dsc.aux_reader->addReaderToObject(*(void**)dsc.object, evt_id); } break; } @@ -513,95 +503,6 @@ RootTreeContainer::loadObject(DataCallBack* call, Token::OID_t& oid, DbAccessMod - -TBranch* -RootTreeContainer::findAuxBranch(const SG::auxid_t& auxid) -{ - auto abr_it = m_auxBranchMap.find(auxid); - if( abr_it != m_auxBranchMap.end() ) { - return abr_it->second.branch; - } - // cout << " -- looking for branch for ID=" << auxid << endl; - string attr_name = SG::AuxTypeRegistry::instance().getName(auxid); - TBranch* branch = m_tree->GetBranch( auxBranchName(attr_name).c_str() ); - // remember the result (even null) to not call GetBranch again - m_auxBranchMap[auxid].branch = branch; - return branch; -} - - -DbStatus -RootTreeContainer::readAuxBranch(const SG::auxid_t& auxid, void* data, long long entry) -{ - TBranch* branch = findAuxBranch(auxid); - if( !branch ) { - string attr_name = SG::AuxTypeRegistry::instance().getName(auxid); - DbPrint log(m_name); - log << DbPrintLvl::Error << "Branch " << auxBranchName(attr_name) << " for attribute: " - << attr_name << " with ID=" << auxid << " not found" << DbPrint::endmsg; - return Error; - } - return readAuxBranch(*branch, data, entry); -} - - -// this can be called to avoid looking up the branch, if it is already known -DbStatus -RootTreeContainer::readAuxBranch(TBranch& branch, void* data, long long entry) -{ - if(data) branch.SetAddress(data); // 0 for basic types - int nbytes = branch.GetEntry(entry); - if( nbytes < 1 ) { - DbPrint log(m_name); - log << DbPrintLvl::Error << "Error reading AUX branch " << branch.GetName() - << " for entry No." << entry << DbPrint::endmsg; - m_ioBytes = -1; - return Error; - } - m_ioBytes = nbytes; - m_rootDb->addByteCount(RootDatabase::READ_COUNTER, nbytes); - return Success; -} - - - -DbStatus -RootTreeContainer::readAuxBranch(TBranch& branch, void* data, const std::type_info *tinf, long long entry) -{ - TClass *tc = TClass::GetClass(*tinf); - EDataType edt = kOther_t; - if( !tc ) { - edt = TDataType::GetType(*tinf); - if( edt <=0 ) { - DbPrint log(m_name); - log << DbPrintLvl::Error << "Error determining ROOT type for AUX branch " << branch.GetName() - << " typeinfo=" << tinf->name() << DbPrint::endmsg; - m_ioBytes = -1; - return Error; - } - } - Int_t status = 0; - if( ( status = m_tree->SetBranchAddress( branch.GetName(), data, tc, edt, true ) ) < 0 ) { - DbPrint log(m_name); - log << DbPrintLvl::Error << "Error setting up AUX branch " << branch.GetName() << DbPrint::endmsg; - m_ioBytes = -1; - return Error; - } - int nbytes = branch.GetEntry(entry); - if( nbytes < 1 ) { - DbPrint log(m_name); - log << DbPrintLvl::Error << "Error reading AUX branch " << branch.GetName() - << " for entry No." << entry << DbPrint::endmsg; - m_ioBytes = -1; - return Error; - } - m_ioBytes = nbytes; - m_rootDb->addByteCount(RootDatabase::READ_COUNTER, nbytes); - return Success; -} - - - DbStatus RootTreeContainer::close() { m_dbH = DbDatabase(POOL_StorageType); if ( m_tree ) { @@ -634,258 +535,243 @@ DbStatus RootTreeContainer::open( const DbDatabase& dbH, const DbTypeInfo* info, DbAccessMode mode) { - DbPrint log(dbH.name()); - m_branches.clear(); - m_name = nam; - if ( dbH.isValid() && info ) { - const DbTypeInfo::Columns& cols = info->columns(); - DbTypeInfo::Columns::const_iterator i; - std::string treeName(nam); - for(std::string::iterator j = treeName.begin(); j != treeName.end(); ++j ) { - if ( *j == '/' ) *j = '_'; - } - if (cols.size() == 1) { - std::string::size_type inx = nam.find('('); - if (inx != std::string::npos) { - std::string::size_type inx2 = nam.find(')'); - if (inx2 == std::string::npos || inx2 != nam.size()-1) { - log << DbPrintLvl::Error << "Misspecified branch name in " << m_name << "." - << DbPrint::endmsg; - return Error; - } - m_branchName = treeName.substr(inx+1, inx2-inx-1); - treeName = treeName.substr(0, inx); + DbPrint log(nam); + m_branches.clear(); + m_name = nam; + log << DbPrintLvl::Debug << "Opening" << DbPrint::endmsg; + if ( dbH.isValid() && info ) { + const DbTypeInfo::Columns& cols = info->columns(); + DbTypeInfo::Columns::const_iterator i; + std::string treeName(nam); + for(std::string::iterator j = treeName.begin(); j != treeName.end(); ++j ) { + if ( *j == '/' ) *j = '_'; } - } - IDbDatabase* idb = dbH.info(); - m_rootDb = dynamic_cast<RootDatabase*>(idb); - TDirectory::TContext dirCtxt(m_rootDb ? m_rootDb->file() : gDirectory); - if (m_rootDb) - m_tree = (TTree*)m_rootDb->file()->Get(treeName.c_str()); + log << DbPrintLvl::Debug << " attributes# = " << cols.size() << DbPrint::endmsg; + if (cols.size() == 1) { + // extract tree and branch name for branch containers, notation: "tree(branch)" + std::string::size_type inx = nam.find('('); + if (inx != std::string::npos) { + std::string::size_type inx2 = nam.find(')'); + if (inx2 == std::string::npos || inx2 != nam.size()-1) { + log << DbPrintLvl::Error << "Misspecified branch name in " << m_name << "." + << DbPrint::endmsg; + return Error; + } + m_branchName = treeName.substr(inx+1, inx2-inx-1); + treeName = treeName.substr(0, inx); + log << DbPrintLvl::Debug << "Branch container '" << m_branchName << "'" << DbPrint::endmsg; + } + } + IDbDatabase* idb = dbH.info(); + m_rootDb = dynamic_cast<RootDatabase*>(idb); + TDirectory::TContext dirCtxt(m_rootDb ? m_rootDb->file() : gDirectory); + if (m_rootDb) + m_tree = (TTree*)m_rootDb->file()->Get(treeName.c_str()); - bool hasBeenCreated = (m_branchName.empty() + bool hasBeenCreated = (m_branchName.empty() ? m_tree != 0 : (m_tree && m_tree->GetBranch(m_branchName.c_str()) != 0)); - if ( hasBeenCreated && (mode&pool::READ || mode&pool::UPDATE) ) { - int count; - if ( !m_tree->InheritsFrom(TTree::Class()) ) { - log << DbPrintLvl::Error << "Cannot open the container " << m_name << " of type " - << ROOTTREE_StorageType.storageName() << "." << DbPrint::endmsg - << "The specified container is not a ROOT " << (m_branchName.empty() ? "Tree" : "Branch") - << ", but rather of class " << m_tree->IsA()->GetName() << "." - << DbPrint::endmsg; - return Error; - } - m_branches.resize(cols.size()); - for(i = cols.begin(), count = 0; i != cols.end(); ++i, ++count ) { - std::string cnam = (m_branchName.empty() ? (*i)->name() : m_branchName); - const char* col_nam = cnam.c_str(); - TBranch* pBranch = m_tree->GetBranch(col_nam); - if (!pBranch && m_branchName.empty()) { - for ( std::string::iterator j = cnam.begin(); j != cnam.end(); ++j ) { - if ( !::isalnum(*j) ) *j = '_'; - } - col_nam = cnam.c_str(); - pBranch = m_tree->GetBranch(col_nam); - } - if ( pBranch ) { - fixupPackedConversion (pBranch); - - const DbColumn* c = *i; - BranchDesc& dsc = m_branches[count]; - TClass* cl = 0; - TLeaf* leaf = pBranch->GetLeaf(col_nam); - switch ( (*i)->typeID() ) { - case DbColumn::ANY: - case DbColumn::BLOB: - case DbColumn::POINTER: - cl = TClass::GetClass(pBranch->GetClassName()); - if ( 0 == cl ) { - log << DbPrintLvl::Debug << "Cannot open the container " << m_name << " of type " - << ROOTTREE_StorageType.storageName() - << " Class " << pBranch->GetClassName() << " is unknown." - << DbPrint::endmsg; - return Error; - } - dsc = BranchDesc(cl,pBranch,leaf,cl->New(),c); - if ( (m_name.size() >= 5 && m_name.substr(m_name.size()-5, 4) == SG::AUX_POSTFIX) - || info->clazz().Properties().HasProperty("IAuxStore") ) { - TClass *storeTC = cl->GetBaseClass("SG::IAuxStoreHolder"); - if( storeTC ) { - dsc.aux_storehdl_IFoffset = cl->GetBaseClassOffset( storeTC ); - string branch_prefix = auxBranchName(""); - TObjArray *all_branches = m_tree->GetListOfBranches(); - for( int i=0; i<all_branches->GetEntriesFast(); i++ ) { - const char *bname = (*all_branches)[i]->GetName(); - if( strncmp(bname, branch_prefix.c_str(), branch_prefix.size()) == 0 ) { - const char *attr_name = bname+branch_prefix.size(); - // cout << " >>> Branch " << bname << ", attr=" << attr_name << endl; - m_auxBranches[attr_name] = (TBranch*)(*all_branches)[i]; - } - } - } - } - break; - case DbColumn::CHAR: - case DbColumn::UCHAR: - case DbColumn::BOOL: - case DbColumn::SHORT: - case DbColumn::USHORT: - case DbColumn::INT: - case DbColumn::LONG: - case DbColumn::UINT: - case DbColumn::ULONG: - case DbColumn::FLOAT: - case DbColumn::DOUBLE: - case DbColumn::LONGLONG: - case DbColumn::ULONGLONG: - case DbColumn::STRING: - case DbColumn::LONG_STRING: - case DbColumn::NTCHAR: - case DbColumn::LONG_NTCHAR: - case DbColumn::TOKEN: - dsc.clazz = 0; - dsc.leaf = leaf; - dsc.branch = pBranch; - dsc.buffer = 0; - dsc.object = 0; - dsc.column = *i; - break; - default: + if ( hasBeenCreated && (mode&pool::READ || mode&pool::UPDATE) ) { + int count; + if ( !m_tree->InheritsFrom(TTree::Class()) ) { + log << DbPrintLvl::Error << "Cannot open the container " << m_name << " of type " + << ROOTTREE_StorageType.storageName() << "." << DbPrint::endmsg + << "The specified container is not a ROOT " << (m_branchName.empty() ? "Tree" : "Branch") + << ", but rather of class " << m_tree->IsA()->GetName() << "." + << DbPrint::endmsg; return Error; - } - } - else { - log << DbPrintLvl::Warning << "Branch with name:" << col_nam - << " not present in container:" << m_name << " of type " - << ROOTTREE_StorageType.storageName() - << DbPrint::endmsg; - } - } - log << DbPrintLvl::Debug << "Opened container " << m_name << " of type " - << ROOTTREE_StorageType.storageName() - << DbPrint::endmsg; - m_dbH = dbH; - m_type = info; - if( mode&pool::UPDATE ) { - m_rootDb->registerBranchContainer(this); - } - return Success; - } - else if ( !hasBeenCreated && mode&pool::CREATE ) { - int count, defCompression=1, defSplitLevel=99, - defAutoSave=16*1024*1024, defBufferSize=16*1024, - branchOffsetTabLen=0, containerSplitLevel=defSplitLevel, auxSplitLevel=defSplitLevel; - DbStatus res = Success; - try { - DbOption opt1("DEFAULT_COMPRESSION",""); - DbOption opt2("DEFAULT_SPLITLEVEL",""); - DbOption opt3("DEFAULT_AUTOSAVE",""); - DbOption opt4("DEFAULT_BUFFERSIZE",""); - DbOption opt5("TREE_BRANCH_OFFSETTAB_LEN",""); - DbOption opt6("CONTAINER_SPLITLEVEL", m_name); - DbOption opt7("CONTAINER_SPLITLEVEL", SG::AUX_POSTFIX); - dbH.getOption(opt1); - dbH.getOption(opt2); - dbH.getOption(opt3); - dbH.getOption(opt4); - dbH.getOption(opt5); - dbH.getOption(opt6); - dbH.getOption(opt7); - opt1._getValue(defCompression); - opt2._getValue(defSplitLevel); - opt3._getValue(defAutoSave); - opt4._getValue(defBufferSize); - opt5._getValue(branchOffsetTabLen); - opt6._getValue(containerSplitLevel); - opt7._getValue(auxSplitLevel); - if (containerSplitLevel == defSplitLevel) { - if ( (m_name.size() >= 5 && m_name.substr(m_name.size()-5, 4) == SG::AUX_POSTFIX) - || info->clazz().Properties().HasProperty("IAuxStore") ) containerSplitLevel = auxSplitLevel; - } - if (!m_tree) { - m_tree = new TTree(treeName.c_str(), treeName.c_str(), (m_branchName.empty() ? containerSplitLevel : defSplitLevel)); - if (m_rootDb) - m_tree->SetDirectory(m_rootDb->file()); - // Autosave every mega byte... - m_tree->SetAutoSave(defAutoSave); - } - // - C : a character string terminated by the 0 character - // - B : an 8 bit signed integer (Char_t) - // - b : an 8 bit unsigned integer (UChar_t) - // - S : a 16 bit signed integer (Short_t) - // - s : a 16 bit unsigned integer (UShort_t) - // - I : a 32 bit signed integer (Int_t) - // - i : a 32 bit unsigned integer (UInt_t) - // - F : a 32 bit floating point (Float_t) - // - D : a 64 bit floating point (Double_t) - m_branches.resize(cols.size()); - for (i = cols.begin(), count = 0; i != cols.end(); ++i, ++count ) { - DbStatus iret = Success; - BranchDesc& dsc = m_branches[count]; - switch ( (*i)->typeID() ) { - case DbColumn::CHAR: iret=addBranch(*i,dsc,"/B"); break; - case DbColumn::UCHAR: iret=addBranch(*i,dsc,"/b"); break; - case DbColumn::BOOL: iret=addBranch(*i,dsc,"/O"); break; - case DbColumn::SHORT: iret=addBranch(*i,dsc,"/S"); break; - case DbColumn::USHORT: iret=addBranch(*i,dsc,"/s"); break; - case DbColumn::INT: iret=addBranch(*i,dsc,"/I"); break; - case DbColumn::LONG: iret=addBranch(*i,dsc,"/L"); break; - case DbColumn::UINT: iret=addBranch(*i,dsc,"/i"); break; - case DbColumn::ULONG: iret=addBranch(*i,dsc,"/l"); break; - case DbColumn::FLOAT: iret=addBranch(*i,dsc,"/F"); break; - case DbColumn::DOUBLE: iret=addBranch(*i,dsc,"/D"); break; - case DbColumn::LONGLONG: iret=addBranch(*i,dsc,"/L"); break; - case DbColumn::ULONGLONG: iret=addBranch(*i,dsc,"/l"); break; - case DbColumn::STRING: - case DbColumn::LONG_STRING: - case DbColumn::NTCHAR: - case DbColumn::LONG_NTCHAR: - case DbColumn::TOKEN: - iret=addBranch(*i,dsc,"/C"); - break; - case DbColumn::BLOB: - iret=addObject(*i,dsc,"UCharDbArray", defSplitLevel, defBufferSize, branchOffsetTabLen); - break; - case DbColumn::ANY: - case DbColumn::POINTER: - iret=addObject(*i, dsc, (*i)->typeName(), containerSplitLevel, defBufferSize, branchOffsetTabLen); - break; - default: - return Error; - } - if( !iret.isSuccess() ) { - res = iret; - } - } - if( res.isSuccess() ) { - log << DbPrintLvl::Debug << "Opened container " << m_name << " of type " - << ROOTTREE_StorageType.storageName() - << DbPrint::endmsg; - m_dbH = dbH; - m_type = info; - m_rootDb->registerBranchContainer(this); - return Success; - } - debugBreak(nam, "Cannot open ROOT container(Tree/Branch)", false); - return res; - } - catch( const std::exception& e ) { - debugBreak(nam, "Cannot open ROOT container(Tree/Branch)", e, false); - res = Error; + } + m_branches.resize(cols.size()); + for(i = cols.begin(), count = 0; i != cols.end(); ++i, ++count ) { + std::string colnam = (m_branchName.empty() ? (*i)->name() : m_branchName); + TBranch* pBranch = m_tree->GetBranch(colnam.c_str()); + if( !pBranch && m_branchName.empty() ) { + for( char& c : colnam ) + if( !::isalnum(c) ) c = '_'; + pBranch = m_tree->GetBranch(colnam.c_str()); + } + if ( pBranch ) { + fixupPackedConversion (pBranch); + + const DbColumn* c = *i; + BranchDesc& dsc = m_branches[count]; + TClass* cl = 0; + TLeaf* leaf = pBranch->GetLeaf(colnam.c_str()); + switch ( (*i)->typeID() ) { + case DbColumn::ANY: + case DbColumn::BLOB: + case DbColumn::POINTER: + cl = TClass::GetClass(pBranch->GetClassName()); + if ( 0 == cl ) { + log << DbPrintLvl::Debug << "Cannot open the container " << m_name << " of type " + << ROOTTREE_StorageType.storageName() + << " Class " << pBranch->GetClassName() << " is unknown." + << DbPrint::endmsg; + return Error; + } + dsc = BranchDesc(cl, pBranch, leaf, cl->New(), c); + dsc.aux_reader = RootAuxDynIO::getReaderForBranch(pBranch); + break; + case DbColumn::CHAR: + case DbColumn::UCHAR: + case DbColumn::BOOL: + case DbColumn::SHORT: + case DbColumn::USHORT: + case DbColumn::INT: + case DbColumn::LONG: + case DbColumn::UINT: + case DbColumn::ULONG: + case DbColumn::FLOAT: + case DbColumn::DOUBLE: + case DbColumn::LONGLONG: + case DbColumn::ULONGLONG: + case DbColumn::STRING: + case DbColumn::LONG_STRING: + case DbColumn::NTCHAR: + case DbColumn::LONG_NTCHAR: + case DbColumn::TOKEN: + dsc.clazz = 0; + dsc.leaf = leaf; + dsc.branch = pBranch; + dsc.buffer = 0; + dsc.object = 0; + dsc.column = *i; + break; + default: + return Error; + } + } + else { + log << DbPrintLvl::Warning << "Branch with name:" << colnam + << " not present in container:" << m_name << " of type " + << ROOTTREE_StorageType.storageName() + << DbPrint::endmsg; + } + } + log << DbPrintLvl::Debug << "Opened container " << m_name << " of type " + << ROOTTREE_StorageType.storageName() + << DbPrint::endmsg; + m_dbH = dbH; + m_type = info; + if( mode&pool::UPDATE ) { + m_rootDb->registerBranchContainer(this); + } + return Success; } - catch (...) { - DbPrint err( m_name); - err << DbPrintLvl::Fatal << "Unknown exception occurred. Cannot give more details." - << DbPrint::endmsg; - debugBreak(nam, "Cannot open ROOT container(Tree/Branch)"); - res = Error; + else if ( !hasBeenCreated && mode&pool::CREATE ) { + int count, defCompression=1, defSplitLevel=99, + defAutoSave=16*1024*1024, defBufferSize=16*1024, + branchOffsetTabLen=0, containerSplitLevel=defSplitLevel, auxSplitLevel=defSplitLevel; + DbStatus res = Success; + try { + DbOption opt1("DEFAULT_COMPRESSION",""); + DbOption opt2("DEFAULT_SPLITLEVEL",""); + DbOption opt3("DEFAULT_AUTOSAVE",""); + DbOption opt4("DEFAULT_BUFFERSIZE",""); + DbOption opt5("TREE_BRANCH_OFFSETTAB_LEN",""); + DbOption opt6("CONTAINER_SPLITLEVEL", m_name); + DbOption opt7("CONTAINER_SPLITLEVEL", RootAuxDynIO::AUX_POSTFIX); + dbH.getOption(opt1); + dbH.getOption(opt2); + dbH.getOption(opt3); + dbH.getOption(opt4); + dbH.getOption(opt5); + dbH.getOption(opt6); + dbH.getOption(opt7); + opt1._getValue(defCompression); + opt2._getValue(defSplitLevel); + opt3._getValue(defAutoSave); + opt4._getValue(defBufferSize); + opt5._getValue(branchOffsetTabLen); + opt6._getValue(containerSplitLevel); + opt7._getValue(auxSplitLevel); + if (containerSplitLevel == defSplitLevel) { + if ( (m_name.size() >= 5 && m_name.substr(m_name.size()-5, 4) == RootAuxDynIO::AUX_POSTFIX) + || info->clazz().Properties().HasProperty("IAuxStore") ) containerSplitLevel = auxSplitLevel; + } + if (!m_tree) { + m_tree = new TTree(treeName.c_str(), treeName.c_str(), (m_branchName.empty() ? containerSplitLevel : defSplitLevel)); + if (m_rootDb) + m_tree->SetDirectory(m_rootDb->file()); + // Autosave every mega byte... + m_tree->SetAutoSave(defAutoSave); + } + // - C : a character string terminated by the 0 character + // - B : an 8 bit signed integer (Char_t) + // - b : an 8 bit unsigned integer (UChar_t) + // - S : a 16 bit signed integer (Short_t) + // - s : a 16 bit unsigned integer (UShort_t) + // - I : a 32 bit signed integer (Int_t) + // - i : a 32 bit unsigned integer (UInt_t) + // - F : a 32 bit floating point (Float_t) + // - D : a 64 bit floating point (Double_t) + m_branches.resize(cols.size()); + for (i = cols.begin(), count = 0; i != cols.end(); ++i, ++count ) { + DbStatus iret = Success; + BranchDesc& dsc = m_branches[count]; + switch ( (*i)->typeID() ) { + case DbColumn::CHAR: iret=addBranch(*i,dsc,"/B"); break; + case DbColumn::UCHAR: iret=addBranch(*i,dsc,"/b"); break; + case DbColumn::BOOL: iret=addBranch(*i,dsc,"/O"); break; + case DbColumn::SHORT: iret=addBranch(*i,dsc,"/S"); break; + case DbColumn::USHORT: iret=addBranch(*i,dsc,"/s"); break; + case DbColumn::INT: iret=addBranch(*i,dsc,"/I"); break; + case DbColumn::LONG: iret=addBranch(*i,dsc,"/L"); break; + case DbColumn::UINT: iret=addBranch(*i,dsc,"/i"); break; + case DbColumn::ULONG: iret=addBranch(*i,dsc,"/l"); break; + case DbColumn::FLOAT: iret=addBranch(*i,dsc,"/F"); break; + case DbColumn::DOUBLE: iret=addBranch(*i,dsc,"/D"); break; + case DbColumn::LONGLONG: iret=addBranch(*i,dsc,"/L"); break; + case DbColumn::ULONGLONG: iret=addBranch(*i,dsc,"/l"); break; + case DbColumn::STRING: + case DbColumn::LONG_STRING: + case DbColumn::NTCHAR: + case DbColumn::LONG_NTCHAR: + case DbColumn::TOKEN: + iret=addBranch(*i,dsc,"/C"); + break; + case DbColumn::BLOB: + iret=addObject(*i,dsc,"UCharDbArrayAthena", defSplitLevel, defBufferSize, branchOffsetTabLen); + break; + case DbColumn::ANY: + case DbColumn::POINTER: + iret=addObject(*i, dsc, (*i)->typeName(), containerSplitLevel, defBufferSize, branchOffsetTabLen); + break; + default: + return Error; + } + if( !iret.isSuccess() ) { + res = iret; + } + } + if( res.isSuccess() ) { + log << DbPrintLvl::Debug << "Opened container " << m_name << " of type " + << ROOTTREE_StorageType.storageName() + << DbPrint::endmsg; + m_dbH = dbH; + m_type = info; + m_rootDb->registerBranchContainer(this); + return Success; + } + debugBreak(nam, "Cannot open ROOT container(Tree/Branch)", false); + return res; + } + catch( const std::exception& e ) { + debugBreak(nam, "Cannot open ROOT container(Tree/Branch)", e, false); + res = Error; + } + catch (...) { + DbPrint err( m_name); + err << DbPrintLvl::Fatal << "Unknown exception occurred. Cannot give more details." + << DbPrint::endmsg; + debugBreak(nam, "Cannot open ROOT container(Tree/Branch)"); + res = Error; + } } - } - } - log << DbPrintLvl::Error << "Cannot open container '" << nam << "', invalid Database handle." - << DbPrint::endmsg; - return Error; + } + log << DbPrintLvl::Error << "Cannot open container '" << nam << "', invalid Database handle." + << DbPrint::endmsg; + return Error; } @@ -944,7 +830,7 @@ DbStatus RootTreeContainer::addObject(const DbColumn* col, setBranchOffsetTabLen( dsc.branch, branchOffsetTabLen ); // AUX STORE specifics - if ( (nam.size() >= 4 && nam.substr(nam.size()-4) == SG::AUX_POSTFIX) + if ( (nam.size() >= 4 && nam.substr(nam.size()-4) == RootAuxDynIO::AUX_POSTFIX) || RootType(dsc.clazz->GetName()).Properties().HasProperty("IAuxStore") ) { TClass *storeTClass = dsc.clazz->GetBaseClass("SG::IAuxStoreIO"); if( storeTClass ) { @@ -975,14 +861,6 @@ DbStatus RootTreeContainer::addObject(const DbColumn* col, } -std::string -RootTreeContainer::auxBranchName(const std::string& attr_name) -{ - string branch_name = m_branchName; - if( branch_name.back() == '.' ) branch_name.pop_back(); - branch_name += SG::AUXDYN_POSTFIX + attr_name; - return branch_name; -} void RootTreeContainer::createBasicAuxBranch(const std::string& branchname, const std::string& leafname, BranchDesc& dsc) @@ -1000,7 +878,7 @@ DbStatus RootTreeContainer::addAuxBranch(const std::string& attribute, BranchDesc& dsc) { string typenam = SG::normalizedTypeinfoName(*typeinfo); - string branch_name = auxBranchName(attribute); + string branch_name = RootAuxDynIO::auxBranchName(attribute, m_branchName); dsc.branch = 0; try { if( *typeinfo == typeid(UInt_t) ) @@ -1113,7 +991,13 @@ DbStatus RootTreeContainer::getOption(DbOption& opt) const { if ( m_tree ) { const char* n = opt.name().c_str(); if ( !strcasecmp(n,"BYTES_IO") ) { - return opt._setValue((int)m_ioBytes); + for( auto& branch: m_branches ) { + if( branch.aux_reader ) { + const_cast<RootTreeContainer*>(this)->m_ioBytes += branch.aux_reader->getBytesRead(); + branch.aux_reader->resetBytesRead(); + } + } + return opt._setValue((int)m_ioBytes); } else if ( !strcasecmp(n,"BRANCH") ) { TBranch* b = branch(opt.option()); diff --git a/Database/APR/RootStorageSvc/src/RootTreeContainer.h b/Database/APR/RootStorageSvc/src/RootTreeContainer.h index 3617878a439a8e50de27e2a178261d7dbe391600..2a976de2606641291719125fdb12d74cd2a54020 100755 --- a/Database/APR/RootStorageSvc/src/RootTreeContainer.h +++ b/Database/APR/RootStorageSvc/src/RootTreeContainer.h @@ -32,6 +32,9 @@ class TTree; class TLeaf; class TClass; +class IRootAuxDynReader; + + /* * POOL namespace declaration */ @@ -40,7 +43,6 @@ namespace pool { // Forward declaration class DbColumn; class RootDatabase; - class AuxStoreAPR; /** @class RootTreeContainer RootTreeContainer.h src/RootTreeContainer.h * @@ -58,7 +60,6 @@ namespace pool { */ class RootTreeContainer : public DbContainerImp { - friend class AuxStoreAPR; /// Definiton of a branch descriptor struct BranchDesc { public: @@ -70,11 +71,11 @@ namespace pool { const DbColumn* column; // extra variables used by Aux dynamic size_t rows_written = 0; - int aux_storehdl_IFoffset = -1; + // AuxDyn reader if used by this branch + IRootAuxDynReader*aux_reader = 0; int aux_iostore_IFoffset = -1; bool is_basic_type = false; bool written = false; - bool aux_type_different = false; BranchDesc() : clazz(0), @@ -125,7 +126,6 @@ namespace pool { /// aux branches by auxid, used for AuxStore I/O std::map<SG::auxid_t, BranchDesc> m_auxBranchMap; - std::map<std::string, TBranch*> m_auxBranches; private: @@ -155,9 +155,6 @@ namespace pool { // Routine needed for TRANSACT_FLUSH, if branch is specified by user. DbStatus finishTransAct(); - /// construct branch name for dynamic aux attribute - std::string auxBranchName(const std::string& attr_name); - /// Access branch by name TBranch* branch(const std::string& nam) const; @@ -243,18 +240,6 @@ namespace pool { DbAccessMode mode); - /// Find (in the current open file) TBranch for AUX attribute auxid - TBranch* findAuxBranch(const SG::auxid_t& auxid); - - /// Read entry from a branch for AUX attribute auxid into data buffer - DbStatus readAuxBranch(const SG::auxid_t &auxid, void* data, long long entry); - - /// Read entry from an AUX branch into data buffer - DbStatus readAuxBranch(TBranch& branch, void* data, long long entry); - - /// Read entry from an AUX branch into data buffer corresponding to type 'tinf' - DbStatus readAuxBranch(TBranch& branch, void* data, const std::type_info *tinf, long long entry); - /// Create TBranch for a basic type (ROOT type notation given in the leafname) void createBasicAuxBranch(const std::string& branchname, const std::string& leafname, diff --git a/Database/APR/RootStorageSvc/test/RootAuxVectorFactory_test.cxx b/Database/APR/RootStorageSvc/test/RootAuxVectorFactory_test.cxx deleted file mode 100644 index 818e669e533bc15bdee68a85ba12c153a92ba55c..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/test/RootAuxVectorFactory_test.cxx +++ /dev/null @@ -1,218 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -// $Id$ -/** - * @file RootAuxVectorFactory_test.cxx - * @author scott snyder <snyder@bnl.gov> - * @date May, 2014 - * @brief Regression test for RootAuxVectorFactory. - */ - - -#undef NDEBUG -#include "../src/RootAuxVectorFactory.h" -#include "CxxUtils/StrFormat.h" -#include "TClass.h" -#include <iostream> -#include <cassert> - - -std::string str (int x) -{ - return CxxUtils::strformat ("%d", x); -} - - -void test1() -{ - std::cout << "test1\n"; - TClass* cl = TClass::GetClass ("vector<int>"); - pool::RootAuxVectorFactory fac (cl); - SG::IAuxTypeVector* vec = new pool::RootAuxVector (&fac, 10, 10); - assert (vec->size() == 10); - int* ptr = reinterpret_cast<int*> (vec->toPtr()); - for (int i=0; i < 10; i++) - ptr[i] = i+1; - vec->resize (100); - vec->reserve (100); - ptr = reinterpret_cast<int*> (vec->toPtr()); - for (int i=0; i < 10; i++) - assert (ptr[i] == i+1); - std::vector<int>* pvec = reinterpret_cast<std::vector<int>*> (vec->toVector()); - assert (pvec->size() == 100); - for (int i=0; i < 10; i++) - assert ((*pvec)[i] == i+1); - - // 1 2 3 4 5 6 7 8 9 10 - - vec->resize (10); - vec->shift (7, -3); - assert (vec->size() == 7); - // 1 2 3 4 8 9 10 - ptr = reinterpret_cast<int*> (vec->toPtr()); - assert (ptr[0] == 1); - assert (ptr[1] == 2); - assert (ptr[2] == 3); - assert (ptr[3] == 4); - assert (ptr[4] == 8); - assert (ptr[5] == 9); - assert (ptr[6] == 10); - - vec->shift (3, 2); - assert (vec->size() == 9); - // 1 2 3 0 0 4 8 9 10 - ptr = reinterpret_cast<int*> (vec->toPtr()); - assert (ptr[0] == 1); - assert (ptr[1] == 2); - assert (ptr[2] == 3); - assert (ptr[3] == 0); - assert (ptr[4] == 0); - assert (ptr[5] == 4); - assert (ptr[6] == 8); - assert (ptr[7] == 9); - assert (ptr[8] == 10); - - SG::IAuxTypeVector* vec2 = vec->clone(); - int* ptr2 = reinterpret_cast<int*> (vec2->toPtr()); - assert (ptr != ptr2); - assert (ptr2[0] == 1); - assert (ptr2[1] == 2); - assert (ptr2[2] == 3); - assert (ptr2[3] == 0); - assert (ptr2[4] == 0); - assert (ptr2[5] == 4); - assert (ptr2[6] == 8); - assert (ptr2[7] == 9); - assert (ptr2[8] == 10); - - - vec->resize (0); - assert (vec->toPtr() == 0); - - delete vec; -} - - -void test2() -{ - std::cout << "test2\n"; - TClass* cl = TClass::GetClass ("vector<std::string>"); - pool::RootAuxVectorFactory fac (cl); - SG::IAuxTypeVector* vec = new pool::RootAuxVector (&fac, 10, 10); - assert (vec->size() == 10); - std::string* ptr = reinterpret_cast<std::string*> (vec->toPtr()); - for (int i=0; i < 10; i++) - ptr[i] = str(i+1); - vec->resize (100); - vec->reserve (100); - ptr = reinterpret_cast<std::string*> (vec->toPtr()); - for (int i=0; i < 10; i++) - assert (ptr[i] == str(i+1)); - std::vector<std::string>* pvec = reinterpret_cast<std::vector<std::string>*> (vec->toVector()); - assert (pvec->size() == 100); - for (int i=0; i < 10; i++) - assert ((*pvec)[i] == str(i+1)); - - // 1 2 3 4 5 6 7 8 9 10 - - vec->resize (10); - vec->shift (7, -3); - assert (vec->size() == 7); - // 1 2 3 4 8 9 10 - ptr = reinterpret_cast<std::string*> (vec->toPtr()); - assert (ptr[0] == str(1)); - assert (ptr[1] == str(2)); - assert (ptr[2] == str(3)); - assert (ptr[3] == str(4)); - assert (ptr[4] == str(8)); - assert (ptr[5] == str(9)); - assert (ptr[6] == str(10)); - - vec->shift (3, 2); - assert (vec->size() == 9); - // 1 2 3 "" "" 4 8 9 10 - ptr = reinterpret_cast<std::string*> (vec->toPtr()); - assert (ptr[0] == str(1)); - assert (ptr[1] == str(2)); - assert (ptr[2] == str(3)); - assert (ptr[3] == ""); - assert (ptr[4] == ""); - assert (ptr[5] == str(4)); - assert (ptr[6] == str(8)); - assert (ptr[7] == str(9)); - assert (ptr[8] == str(10)); - - delete vec; -} - - -void test3() -{ - std::cout << "test3\n"; - TClass* cl = TClass::GetClass ("vector<int>"); - pool::RootAuxVectorFactory fac (cl); - assert (fac.vecClass() == cl); - assert (fac.getEltSize() == sizeof(int)); - assert (fac.tiVec() == &typeid(std::vector<int>)); - assert (fac.isDynamic()); - SG::IAuxTypeVector* vec = fac.create (10, 10); - assert (vec->size() == 10); - - int* ptr = reinterpret_cast<int*> (vec->toPtr()); - ptr[0] = 1; - ptr[1] = 2; - fac.copy (ptr, 5, ptr, 1); - assert (ptr[1] == 2); - assert (ptr[5] == 2); - - fac.clear (ptr, 1); - assert (ptr[1] == 0); - - fac.swap (ptr, 0, ptr, 5); - assert (ptr[0] == 2); - assert (ptr[5] == 1); - - delete vec; -} - - -void test4() -{ - std::cout << "test4\n"; - TClass* cl = TClass::GetClass ("vector<std::string>"); - pool::RootAuxVectorFactory fac (cl); - assert (fac.vecClass() == cl); - assert (fac.getEltSize() == sizeof(std::string)); - assert (fac.tiVec() == &typeid(std::vector<std::string>)); - assert (fac.isDynamic()); - SG::IAuxTypeVector* vec = fac.create (10, 10); - assert (vec->size() == 10); - - std::string* ptr = reinterpret_cast<std::string*> (vec->toPtr()); - ptr[0] = "1"; - ptr[1] = "2"; - fac.copy (ptr, 5, ptr, 1); - assert (ptr[1] == "2"); - assert (ptr[5] == "2"); - - fac.clear (ptr, 1); - assert (ptr[1] == ""); - - fac.swap (ptr, 0, ptr, 5); - assert (ptr[0] == "2"); - assert (ptr[5] == "1"); - - delete vec; -} - - -int main() -{ - test1(); - test2(); - test3(); - test4(); - return 0; -} diff --git a/Database/APR/RootStorageSvc/test/RootStorageSvc.xml b/Database/APR/RootStorageSvc/test/RootStorageSvc.xml deleted file mode 100644 index 1148d4909ffe48147a68f2999f6d614165ea5d60..0000000000000000000000000000000000000000 --- a/Database/APR/RootStorageSvc/test/RootStorageSvc.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<atn> - <TEST name="RootStorageSvcTest" type="makecheck" suite="Examples"> - <package>Database/APR/RootStorageSvc</package> - <timelimit>40</timelimit> - <author> scott snyder </author> - <mailto> snyder@bnl.gov, Marcin.Nowak@cern.ch </mailto> - <expectations> - <errorMessage>Athena exited abnormally</errorMessage> - <errorMessage>differ</errorMessage> - <warningMessage> # WARNING_MESSAGE : post.sh> ERROR</warningMessage> - <successMessage>check ok</successMessage> - <returnValue>0</returnValue> - </expectations> - </TEST> -</atn>