diff --git a/Database/APR/RootStorageSvc/CMakeLists.txt b/Database/APR/RootStorageSvc/CMakeLists.txt index beabda2ad977a6f6874576f6e3d18f9c52aa8f9f..6ed8e0ac2b1b7bf5449f07952e4c0dd6a24ec28b 100644 --- a/Database/APR/RootStorageSvc/CMakeLists.txt +++ b/Database/APR/RootStorageSvc/CMakeLists.txt @@ -30,6 +30,5 @@ atlas_add_library( RootStorageSvc RootUtils StorageSvc RootAuxDynIO POOLCore PersistentDataModel GaudiKernel ) - # Component list generation: atlas_generate_componentslist( RootStorageSvc ) diff --git a/Database/APR/RootStorageSvc/src/RootOODb.cpp b/Database/APR/RootStorageSvc/src/RootOODb.cpp index 85af763c8b3f59c2ea40a90f48703c9da3782a4f..e92a7419811fb00bae84fb23995c6921e0bdc2f3 100755 --- a/Database/APR/RootStorageSvc/src/RootOODb.cpp +++ b/Database/APR/RootStorageSvc/src/RootOODb.cpp @@ -15,12 +15,14 @@ #include "RootDomain.h" #include "RootKeyContainer.h" #include "RootTreeContainer.h" +#include "RootTreeIndexContainer.h" #include "StorageSvc/DbInstanceCount.h" // declare the types provided by this Storage plugin DECLARE_COMPONENT_WITH_ID(pool::RootOODb, "ROOT_All") -DECLARE_COMPONENT_WITH_ID(pool::RootOOTree, "ROOT_Tree") DECLARE_COMPONENT_WITH_ID(pool::RootOOKey, "ROOT_Key") +DECLARE_COMPONENT_WITH_ID(pool::RootOOTree, "ROOT_Tree") +DECLARE_COMPONENT_WITH_ID(pool::RootOOTreeIndex, "ROOT_TreeIndex") using namespace pool; @@ -51,13 +53,16 @@ IDbDatabase* RootOODb::createDatabase() { } /// Create Root Container object -IDbContainer* RootOODb::createContainer(const DbType& typ) { +IDbContainer* RootOODb::createContainer(const DbType& typ) { if ( typ.match(ROOTKEY_StorageType) ) { return new RootKeyContainer(); } else if ( typ.match(ROOTTREE_StorageType) ) { return new RootTreeContainer(); } + else if ( typ.match(ROOTTREEINDEX_StorageType) ) { + return new RootTreeIndexContainer(); + } else if ( typ.match(ROOT_StorageType) ) { return new RootTreeContainer(); } diff --git a/Database/APR/RootStorageSvc/src/RootOODb.h b/Database/APR/RootStorageSvc/src/RootOODb.h index 051a49012cf756a2a1d845ee49609b629671d750..c686d1ada6c63445fd16fd6b1eca874bb91d9ebd 100755 --- a/Database/APR/RootStorageSvc/src/RootOODb.h +++ b/Database/APR/RootStorageSvc/src/RootOODb.h @@ -58,6 +58,14 @@ namespace pool { IDbContainer* createContainer(const DbType& typ); }; + class RootOOKey : public RootOODb { + public: + /// Standard Constructor + RootOOKey() : RootOODb(ROOTKEY_StorageType) { } + /// Label of the specific class + static const char* catalogLabel() { return "ROOT_Key"; } + }; + class RootOOTree : public RootOODb { public: /// Standard Constructor @@ -65,15 +73,15 @@ namespace pool { /// Label of the specific class static const char* catalogLabel() { return "ROOT_Tree"; } }; - - class RootOOKey : public RootOODb { + + class RootOOTreeIndex : public RootOODb { public: /// Standard Constructor - RootOOKey() : RootOODb(ROOTKEY_StorageType) { } + RootOOTreeIndex() : RootOODb(ROOTTREEINDEX_StorageType) { } /// Label of the specific class - static const char* catalogLabel() { return "ROOT_Key"; } + static const char* catalogLabel() { return "ROOT_TreeIndex"; } }; - + } // end namespace pool #endif /* POOL_ROOTSTORAGESVC_ROOTOODB_H */ diff --git a/Database/APR/RootStorageSvc/src/RootTreeContainer.h b/Database/APR/RootStorageSvc/src/RootTreeContainer.h index 89e1af1c70f644fe4d432bc2dc5e6595adcda683..263da5af73997e6dfe640b7258e2b539ce5fb0f8 100755 --- a/Database/APR/RootStorageSvc/src/RootTreeContainer.h +++ b/Database/APR/RootStorageSvc/src/RootTreeContainer.h @@ -104,6 +104,7 @@ namespace pool { /// Definition of the branch container typedef std::vector<BranchDesc> Branches; + protected: /// Reference to the root tree object TTree* m_tree; /// reference to exact type description diff --git a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ceaf9f778cb5774e82eb45b7ad5106666ed09aa --- /dev/null +++ b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + * */ + +// Local implementation files +#include "RootTreeIndexContainer.h" + +#include "StorageSvc/Transaction.h" + +#include "RootDataPtr.h" +#include "RootDatabase.h" + +// Root include files +#include "TTree.h" +#include "TBranch.h" + +using namespace pool; +using namespace std; + +RootTreeIndexContainer::RootTreeIndexContainer() : RootTreeContainer(), m_index_ref(nullptr), m_index_foreign(nullptr), m_index_multi(0), m_index(nullptr) { + m_index = new long long int; + m_index_multi = getpid(); +} + +/// Standard destructor +RootTreeIndexContainer::~RootTreeIndexContainer() { + delete m_index; m_index = nullptr; +} + +long long int RootTreeIndexContainer::nextRecordId() { + long long int s = m_index_multi; + s = s << 32; + if (m_tree != nullptr) { + if (m_index_foreign != nullptr) { + s += m_index_foreign->GetEntries(); + } else { + m_index_foreign = (TBranch*)m_tree->GetBranch("index_ref"); + if (m_index_foreign != nullptr) { + s += m_index_foreign->GetEntries(); + } + } + } + return s; +} + +DbStatus RootTreeIndexContainer::transAct(Transaction::Action action) { + if (action == Transaction::TRANSACT_COMMIT) { + if (m_tree == nullptr) return Error; + if (m_tree->GetName()[0] != '#') { + if (m_index_foreign == nullptr && m_tree->GetBranch("index_ref") == nullptr) { + m_index_ref = (TBranch*)m_tree->Branch("index_ref", m_index); + } + if (m_index_ref != nullptr && RootTreeContainer::size() > m_index_ref->GetEntries()) { + *m_index = this->nextRecordId(); + m_index_ref->SetAddress(m_index); + if (!m_treeFillMode) m_index_ref->Fill(); + } + } + } + DbStatus status = RootTreeContainer::transAct(action); + if (action == Transaction::TRANSACT_FLUSH) { + if (m_tree->GetName()[0] != '#') { + if (m_index_ref != nullptr && m_tree->GetEntryNumberWithIndex(nextRecordId()) == -1) { + m_tree->BuildIndex("index_ref"); + } + } + } + return status; +} + +DbStatus RootTreeIndexContainer::loadObject(DataCallBack* call, Token::OID_t& oid, DbAccessMode mode) { + if ((oid.second >> 32) > 0) { + long long int evt_id = m_tree->GetEntryNumberWithIndex(oid.second); + if (evt_id == -1) { + m_tree->BuildIndex("index_ref"); + evt_id = m_tree->GetEntryNumberWithIndex(oid.second); + } + if (evt_id >= 0) { + oid.second = evt_id; + } + } + return RootTreeContainer::loadObject(call, oid, mode); +} diff --git a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..d47c06f49881fb8bc0d957c5034d8615783f587b --- /dev/null +++ b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + * */ + +#ifndef POOL_ROOTTREEINDEXCONTAINER_H +#define POOL_ROOTTREEINDEXCONTAINER_H 1 + +#include "RootTreeContainer.h" + +// Forward declarations +class TTree; +class TBranch; + +namespace pool { + /** @class RootTreeIndexContainer RootTreeIndexContainer.h src/RootTreeIndexContainer.h + * + * Description: + * Spezialization of RootTreeContainer + * ROOT specific implementation of Database container. + * Since objects in root are stored in "trees with branches", + * this object corresponds to a tuple (Tree/Branch), where + * each object type (determined by the location of the transient + * object within the data store) is accessed by an index number + * stored inside its tree. + * + * @author N.Dulin, P.v.Gemmeren + * @date 8/1/2018 + * @version 1.0 + */ + + class RootTreeIndexContainer : public RootTreeContainer { + public: + /// Standard constructor + RootTreeIndexContainer(); + + /// Standard destructor + virtual ~RootTreeIndexContainer(); + + /// Number of entries within the container + virtual long long int nextRecordId(); + + /// Execute Transaction action + virtual DbStatus transAct(Transaction::Action action); + + /// Find object by object identifier and load it into memory + /** @param call [IN] Callback to load data + * @param oid [OUT] Object OID + * @param mode [IN] Object access mode + * + * @return Status code indicating success or failure. + */ + virtual DbStatus loadObject(DataCallBack* call, + Token::OID_t& oid, + DbAccessMode mode); + + private: + /// Pointer to index branch + TBranch* m_index_ref; + TBranch* m_index_foreign; + /// Index multiplier (e.g. pid - ppid), fill in c'tor + int m_index_multi; + /// Index (64 bit) + long long int* m_index; + }; +} +#endif //POOL_ROOTTREEINDEXCONTAINER_H diff --git a/Database/APR/StorageSvc/StorageSvc/DbType.h b/Database/APR/StorageSvc/StorageSvc/DbType.h index 2f60a3c68ba9fbb676228103771e3bc5c6acbf1f..3e2af58dbe98fee1c4bc5b983c954033575b826e 100644 --- a/Database/APR/StorageSvc/StorageSvc/DbType.h +++ b/Database/APR/StorageSvc/StorageSvc/DbType.h @@ -99,6 +99,7 @@ namespace pool { static const DbType ROOT_StorageType = makeTechnology(2,0); static const DbType ROOTKEY_StorageType = makeTechnology(2,1); static const DbType ROOTTREE_StorageType = makeTechnology(2,2); + static const DbType ROOTTREEINDEX_StorageType = makeTechnology(2,3); static const DbType OBJY_StorageType = makeTechnology(3,0); static const DbType ACCESS_StorageType = makeTechnology(4,0); static const DbType EXCEL_StorageType = makeTechnology(5,0); diff --git a/Database/APR/StorageSvc/src/DbContainerImp.cpp b/Database/APR/StorageSvc/src/DbContainerImp.cpp index e6d586383b8641b1c7154076de69a091df823bbc..935166976b99754d1211680f77762ff16904a381 100644 --- a/Database/APR/StorageSvc/src/DbContainerImp.cpp +++ b/Database/APR/StorageSvc/src/DbContainerImp.cpp @@ -67,7 +67,7 @@ DbStatus DbContainerImp::close() { /// In place allocation of raw memory for the transient object void* DbContainerImp::allocate(unsigned long siz, DbContainer& cntH, ShapeH shape) { DbObjectHandle<DbObject> objH(cntH.type()); - Token::OID_t objLink(cntH.token()->oid().first, int(nextRecordId())); + Token::OID_t objLink(cntH.token()->oid().first, nextRecordId()); DbHeap::allocate(siz, &cntH, &objLink, &objH); if ( m_stack.size() < m_size+1 ) { m_stack.resize(m_size+1024); @@ -85,7 +85,7 @@ void* DbContainerImp::allocate(unsigned long siz, DbContainer& cntH, ShapeH shap DbStatus DbContainerImp::allocate(DbContainer& cntH, const void* object, ShapeH shape, Token::OID_t& oid) { if ( object ) { oid.first = cntH.token()->oid().first; - oid.second = int(nextRecordId()); + oid.second = nextRecordId(); if ( m_stack.size() < m_size+1 ) { m_stack.resize(m_size+1024); } diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx index a4bfc4823be7319fb6445cded21cde6035908936..82a19920725f3002f4096039390f661698a0b06f 100644 --- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx +++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx @@ -736,12 +736,12 @@ const Token* AthenaPoolCnvSvc::registerForWrite(const Placement* placement, } //______________________________________________________________________________ void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) const { + ATH_MSG_VERBOSE("Requesting object for: " << token->toString()); if (m_doChronoStat) { m_chronoStatSvc->chronoStart("cObjR_ALL"); } if (!m_outputStreamingTool.empty() && m_streamServer < m_outputStreamingTool.size() && m_outputStreamingTool[m_streamServer]->isServer()) { - ATH_MSG_VERBOSE("Requesting object for: " << token->toString()); if (token->dbID() == Guid::null()) { int num = token->oid().first; // Get object from SHM @@ -1100,6 +1100,9 @@ StatusCode AthenaPoolCnvSvc::decodeOutputSpec(std::string& fileSpec, } else if (fileSpec.find("ROOTTREE:") == 0) { outputTech = pool::ROOTTREE_StorageType; fileSpec.erase(0, 9); + } else if (fileSpec.find("ROOTTREEINDEX:") == 0) { + outputTech = pool::ROOTTREEINDEX_StorageType; + fileSpec.erase(0, 14); } return(StatusCode::SUCCESS); } diff --git a/Database/PersistentDataModel/src/DataHeader.cxx b/Database/PersistentDataModel/src/DataHeader.cxx index ef18725bd00fa8d24385df59833f0343bb2b19c1..56d7dc0679a7164681a8dc63a315d9ffb07f683d 100755 --- a/Database/PersistentDataModel/src/DataHeader.cxx +++ b/Database/PersistentDataModel/src/DataHeader.cxx @@ -137,14 +137,7 @@ const Token* DataHeaderElement::getToken() const { } //_____________________________________________________________________________ long DataHeaderElement::getStorageType() const { - const long technology = m_token->technology(); - if (technology == POOL_StorageType - || technology == POOL_ROOT_StorageType - || technology == POOL_ROOTKEY_StorageType - || technology == POOL_ROOTTREE_StorageType) { - return(POOL_StorageType); - } - return(TEST_StorageType); + return(POOL_StorageType); } //_____________________________________________________________________________ const std::vector<unsigned int>& DataHeaderElement::getHashes() const { diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p3.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p3.h index 91dbfed275a9739d67097c84f8fca7527eadd6ae..79ccd6322dc9f7fa257d0fa6c373ed0016cb8b5b 100755 --- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p3.h +++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p3.h @@ -36,7 +36,6 @@ friend class DataHeaderElementCnv_p3; const std::vector<std::string> alias() const; unsigned int oid1() const; unsigned int oid2() const; - void overwriteOid2(unsigned int oid2); private: std::vector<unsigned int> m_clids; diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p4.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p4.h index 01b30567ea73bf94037827812b0f3865e02c6a78..88e88d2579b1a5d6753925c3ee9dc1907c57261e 100755 --- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p4.h +++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p4.h @@ -36,7 +36,6 @@ friend class DataHeaderElementCnv_p4; const std::string& token() const; unsigned int oid1() const; unsigned int oid2() const; - void overwriteOid2(unsigned int oid2); private: std::vector<unsigned int> m_clids; diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p5.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p5.h index 216a7c5fea77fb066ec9f8acfb46f4c5b805d7e2..60ca74637c37435be7f6cd2f68710e070e7e2f16 100755 --- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p5.h +++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p5.h @@ -30,12 +30,11 @@ friend class DataHeaderCnv_p5; friend class DataHeaderElementCnv_p5; const std::string& token() const; - unsigned int oid2() const; - void overwriteOid2(unsigned int oid2); + long long int oid2() const; private: std::string m_token; - unsigned int m_oid2; + long long int m_oid2; }; /** @class DataHeaderForm_p5 diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h index 93493969b48fa442ba3cf105efb2ed85e0d1e29f..bf20624f87240fbeb64e6399a6dfda93d072826a 100755 --- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h +++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h @@ -35,7 +35,6 @@ friend class DataHeaderElementCnv_p6; const std::string& token() const; unsigned long long oid1() const; unsigned long long oid2() const; - void overwriteOid2(unsigned long long oid2); private: std::string m_token; diff --git a/Database/PersistentDataModelTPCnv/src/DataHeader_p3.cxx b/Database/PersistentDataModelTPCnv/src/DataHeader_p3.cxx index e2287534ea7a56ec97ab083d4fb7f1a78a1a9192..a5526b94e181aadfb4b96211bc4849f090c5c285 100755 --- a/Database/PersistentDataModelTPCnv/src/DataHeader_p3.cxx +++ b/Database/PersistentDataModelTPCnv/src/DataHeader_p3.cxx @@ -72,10 +72,6 @@ unsigned int DataHeaderElement_p3::oid2() const { return(m_oid2); } -void DataHeaderElement_p3::overwriteOid2(unsigned int oid2) { - m_oid2 = oid2; -} - DataHeader_p3::DataHeader_p3() : m_DataHeader(), m_InputDataHeader(), m_GuidMap() {} diff --git a/Database/PersistentDataModelTPCnv/src/DataHeader_p4.cxx b/Database/PersistentDataModelTPCnv/src/DataHeader_p4.cxx index a786afdc33c12f2b55466f21be6fa7521cae93ea..f58b57a1b482e4e09469347e5bdedb49473359c9 100755 --- a/Database/PersistentDataModelTPCnv/src/DataHeader_p4.cxx +++ b/Database/PersistentDataModelTPCnv/src/DataHeader_p4.cxx @@ -72,10 +72,6 @@ unsigned int DataHeaderElement_p4::oid2() const { return(m_oid2); } -void DataHeaderElement_p4::overwriteOid2(unsigned int oid2) { - m_oid2 = oid2; -} - DataHeader_p4::DataHeader_p4() : m_dataHeader(), m_provSize(0U), m_guidMap() {} DataHeader_p4::DataHeader_p4(const DataHeader_p4& rhs) : m_dataHeader(rhs.m_dataHeader), diff --git a/Database/PersistentDataModelTPCnv/src/DataHeader_p5.cxx b/Database/PersistentDataModelTPCnv/src/DataHeader_p5.cxx index e8a52f0ab79eaf00abcf748428853eb841a706b5..bf65e470fa97c39dd62170a63218faae14ba863b 100755 --- a/Database/PersistentDataModelTPCnv/src/DataHeader_p5.cxx +++ b/Database/PersistentDataModelTPCnv/src/DataHeader_p5.cxx @@ -26,14 +26,10 @@ const std::string& DataHeaderElement_p5::token() const { return(m_token); } -unsigned int DataHeaderElement_p5::oid2() const { +long long int DataHeaderElement_p5::oid2() const { return(m_oid2); } -void DataHeaderElement_p5::overwriteOid2(unsigned int oid2) { - m_oid2 = oid2; -} - DataHeaderForm_p5::DataHeaderForm_p5() : m_map(), m_uints(), m_entry(0U) {} DataHeaderForm_p5::DataHeaderForm_p5(const DataHeaderForm_p5& rhs) : m_map(rhs.m_map), m_uints(rhs.m_uints), m_entry(0U) {} diff --git a/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx b/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx index 554ecff84d0b62f2149d987eb22890e9b889113d..5cc3f49f7915683f945e36258e2d0933e1448f73 100755 --- a/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx +++ b/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx @@ -45,10 +45,6 @@ unsigned long long DataHeaderElement_p6::oid2() const { return(m_oid2); } -void DataHeaderElement_p6::overwriteOid2(unsigned long long oid2) { - m_oid2 = oid2; -} - DataHeaderForm_p6::DataHeaderForm_p6() : m_uints(), m_dbRecords(), m_objRecords(), m_objAlias(), m_objSymLinks(), m_objHashes(), m_entry(0U) {} DataHeaderForm_p6::DataHeaderForm_p6(const DataHeaderForm_p6& rhs) : m_uints(rhs.m_uints), m_dbRecords(rhs.m_dbRecords), m_objRecords(rhs.m_objRecords), m_objAlias(rhs.m_objAlias), m_objSymLinks(rhs.m_objSymLinks), m_objHashes(rhs.m_objHashes), m_entry(0U) {}