diff --git a/Database/APR/RootStorageSvc/share/branchContIdx_test.ref b/Database/APR/RootStorageSvc/share/branchContIdx_test.ref index b136da4a515940bba6fe6096163822f6a33e8b05..2478df0436b7f274fc0f85a76fc3c53524374556 100644 --- a/Database/APR/RootStorageSvc/share/branchContIdx_test.ref +++ b/Database/APR/RootStorageSvc/share/branchContIdx_test.ref @@ -2,19 +2,28 @@ Starting branchContIdx_test Start WRITE session Session connect Sample Tokens to written objects: -Token for object A1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000000] -Token for object A2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000001] -Token for object A3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000002] -Token for object A4 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000003] -Token for object A5 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000004] -Token for object A6 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000003-000072F700000005] -Token for object B1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000004-000072F700000000] -Token for object B2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=000072F700000004-000072F700000001] +Token for object A1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000000] +Token for object A2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000001] +Token for object A3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000002] +Token for object A4 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000003] +Token for object A5 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000004] +Token for object A6 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(A)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000003-0000038C00000005] +Token for object B1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000004-0000038C00000000] +Token for object B2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000004-0000038C00000001] +Token for object B3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=Containers(B)][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000004-0000038C00000002] +Token for object C1 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=ContainerC][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000005-0000038C00000000] +Token for object C2 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=ContainerC][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000005-0000038C00000003] +Token for object C3 = [DB=6222A3B2-4F2A-1F4F-027F-34B2FF2534B8][CNT=ContainerC][CLID=DA8F479C-09BC-49D4-94BC-99D025A23A3B][TECH=00000203][OID=0000038C00000005-0000038C00000006] Starting READ read back A1: This is my string A1 +read back A7: This is my string A7 +read back C3: This is my string C3 read back B1: This is my string B1 +read back C2: This is my string C2 read back A3: This is my string A3 +read back C1: This is my string C1 +read back B3: This is my string B3 read back A6: This is my string A6 read back A4: This is my string A4 read back B2: This is my string B2 diff --git a/Database/APR/RootStorageSvc/src/RootDatabase.cpp b/Database/APR/RootStorageSvc/src/RootDatabase.cpp index 3740ebadd3652590dfb79eaba6e583d37913bd94..03e2fad9fe82e4f0d9e6eaf60c8b9d5d20449077 100644 --- a/Database/APR/RootStorageSvc/src/RootDatabase.cpp +++ b/Database/APR/RootStorageSvc/src/RootDatabase.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -21,7 +21,6 @@ #include "GaudiKernel/ISvcLocator.h" #include "GaudiKernel/IFileMgr.h" -#include <iostream> #include <string> #include <cerrno> @@ -49,6 +48,7 @@ RootDatabase::RootDatabase() : m_defWritePolicy(TObject::kOverwrite), // On write create new versions m_branchOffsetTabLen(0), m_defTreeCacheLearnEvents(-1), + m_indexMasterID(0), m_fileMgr(nullptr) { m_counters[READ_COUNTER] = m_counters[WRITE_COUNTER] = m_counters[OTHER_COUNTER] = 0; @@ -73,6 +73,7 @@ long long int RootDatabase::size() const { /// Callback after successful open of a database object DbStatus RootDatabase::onOpen(DbDatabase& dbH, DbAccessMode mode) { + m_dbH = dbH; std::string par_val; DbPrint log("RootDatabase.onOpen"); if ( !dbH.param("FORMAT_VSN", par_val).isSuccess() ) { @@ -98,7 +99,8 @@ DbStatus RootDatabase::onOpen(DbDatabase& dbH, DbAccessMode mode) { } // Open a new root Database: Access the TFile -DbStatus RootDatabase::open(const DbDomain& domH,const std::string& nam,DbAccessMode mode) { +DbStatus RootDatabase::open(const DbDomain& domH,const std::string& nam,DbAccessMode mode) +{ DbPrint log("RootDatabase.open"); const char* fname = nam.c_str(); Bool_t result = ( mode == pool::READ ) ? kFALSE : gSystem->AccessPathName(fname, kFileExists); @@ -590,6 +592,19 @@ DbStatus RootDatabase::setOption(const DbOption& opt) { return Success; } break; + case 'I': + if( !strcasecmp(n, "INDEX_MASTER") ) { + DbPrint log("RootDatabase::setOption"); + char *s = nullptr; + if( opt._getValue(s).isSuccess() and s ) { + m_indexMaster = s; + log << DbPrintLvl::Debug << "INDEX_MASTER set to " << m_indexMaster << DbPrint::endmsg; + return Success; + } + log << DbPrintLvl::Debug << "INDEX_MASTER: s=" << (void*)s << DbPrint::endmsg; + return Error; + } + break; case 'M': if ( !strcasecmp(n, "MAXIMUM_BUFFERSIZE") ) // int return opt._getValue(m_maxBufferSize); @@ -622,7 +637,7 @@ DbStatus RootDatabase::setOption(const DbOption& opt) { break; case 'T': if ( !strcasecmp(n+5,"BRANCH_OFFSETTAB_LEN") ) { - return opt._getValue(m_branchOffsetTabLen); + return opt._getValue(m_branchOffsetTabLen); } else if ( !strcasecmp(n+5,"MAX_SIZE") ) { long long int max_size = TTree::GetMaxTreeSize(); @@ -904,7 +919,40 @@ DbStatus RootDatabase::transAct(Transaction::Action action) } } } + + if( !m_indexMaster.empty() ) { + DbPrint log( m_file->GetName() ); + log << DbPrintLvl::Debug << "Synchronizing indexes to master: " << m_indexMaster << DbPrint::endmsg; + std::vector<IDbContainer*> containers; + m_dbH.containers(containers); + m_indexMasterID = 0; + if( m_indexMaster == "*" ) { + // find the biggest index ID + for( auto c : containers ) { + long long nextID = c->nextRecordId() & 0xFFFFFFFF; + if( nextID > m_indexMasterID ) m_indexMasterID = nextID; + } + } else { + // look for the master by name + for( auto c = containers.begin(); c != containers.end(); ++c ) { + if( (*c)->name() == m_indexMaster ) { + m_indexMasterID = (*c)->nextRecordId() & 0xFFFFFFFF; + // cout << "Found master index: " << (*c)->name() << " next ID= " << m_indexMasterID << endl; + containers.erase(c); + break; + } + } + } + // synchronize all container indices + if( m_indexMasterID > 0 ) { + // go back by one, so nextID in other indices is equal the last ID in master + // this works if synchronizing in separate commits - but not in the same commit! + --m_indexMasterID; + for( auto c: containers ) { + c->useNextRecordId( m_indexMasterID ); + } + } + } + return Success; } - - diff --git a/Database/APR/RootStorageSvc/src/RootDatabase.h b/Database/APR/RootStorageSvc/src/RootDatabase.h index e2898c1e75d30139a4b03e6e181d2b8db033d4b2..b27039549055e45d85c469cbd91465b93f9868c1 100644 --- a/Database/APR/RootStorageSvc/src/RootDatabase.h +++ b/Database/APR/RootStorageSvc/src/RootDatabase.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -13,6 +13,7 @@ // Framework include files #include "StorageSvc/IDbDatabase.h" +#include "StorageSvc/DbDatabase.h" #include <set> #include <map> @@ -44,6 +45,8 @@ namespace pool { public: enum { READ_COUNTER = 0, WRITE_COUNTER = 1, OTHER_COUNTER = 2 }; private: + /// Parent Database handle + DbDatabase m_dbH; /// Reference to the actual implemented file TFile* m_file; /// Persistency format version @@ -73,6 +76,11 @@ namespace pool { /// Default tree cache learn events int m_defTreeCacheLearnEvents; + /// name of the container with master index ('*' means use the biggest) + std::string m_indexMaster; + /// nextID of the master index + long long m_indexMasterID; + /* --- variables used with TREE_AUTO_FLUSH option for managing combined TTree::Fill for branch containers */ @@ -84,12 +92,12 @@ namespace pool { std::map< TTree*, ContainerSet_t > m_containersInTree; std::map< std::string, int > m_customSplitLevel; - - IFileMgr* m_fileMgr; + + IFileMgr* m_fileMgr; // mutex to prevent concurrent read I/O from AuxDynReader std::recursive_mutex m_iomutex; - + public: /// Standard Constuctor RootDatabase(); @@ -124,6 +132,8 @@ namespace pool { void registerBranchContainer(RootTreeContainer*); + long long currentIndexMasterID() const { return m_indexMasterID; } + /// provide access to the I/O mutex for AuxDynReader and Containers std::recursive_mutex& ioMutex() { return m_iomutex; } diff --git a/Database/APR/RootStorageSvc/src/RootTreeContainer.h b/Database/APR/RootStorageSvc/src/RootTreeContainer.h index 1dd8e1ba336f1085e64cb6b097701e0877139d42..f5e5f3749ead11faa6d1805fc14163706f0322fe 100755 --- a/Database/APR/RootStorageSvc/src/RootTreeContainer.h +++ b/Database/APR/RootStorageSvc/src/RootTreeContainer.h @@ -138,7 +138,7 @@ namespace pool { /// Parent Database handle DbDatabase m_dbH; /// Root database file reference - RootDatabase* m_rootDb; + RootDatabase* m_rootDb; /// Branch name, if branch is specified by user. std::string m_branchName; /// Number of bytes written/read during last operation. Set to -1 if it failed. @@ -199,7 +199,7 @@ namespace pool { virtual DbStatus open(DbDatabase& dbH, const std::string& nam, const DbTypeInfo* info, - DbAccessMode mod); + DbAccessMode mod) override; /// Access options /** @param opt [IN] Reference to option object. diff --git a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp index e12a05d863d8f0e0fc38e92028bf8829386b2d66..5e2ade1b7bb6429b9202063fb3f157ba7b995d42 100644 --- a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp +++ b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.cpp @@ -1,8 +1,10 @@ /* - * Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration * */ // Local implementation files +#include "StorageSvc/DbOption.h" +#include "RootDatabase.h" #include "RootTreeIndexContainer.h" // Root include files @@ -13,14 +15,35 @@ using namespace pool; using namespace std; RootTreeIndexContainer::RootTreeIndexContainer() : - m_indexBranch(nullptr), m_index_entries(0), m_index_multi( getpid() ) + m_indexBranch(nullptr), m_index_entries(0), m_index_multi( getpid() ), m_indexBump(0) { } +DbStatus RootTreeIndexContainer::open( DbDatabase& dbH, + const std::string& nam, + const DbTypeInfo* info, + DbAccessMode mod) +{ + auto db = static_cast<const RootDatabase*>( dbH.info() ); + m_indexBump = db? db->currentIndexMasterID() : 0; + return RootTreeContainer::open( dbH, nam, info, mod ); +} + + long long int RootTreeIndexContainer::nextRecordId() { long long id = m_index_multi; - return (id << 32) + RootTreeContainer::nextRecordId(); + return (id << 32) + RootTreeContainer::nextRecordId() + m_indexBump; +} + +void RootTreeIndexContainer::useNextRecordId(long long int nextID) +{ + // Find out how this TTree index is behind the master index in the DB + m_indexBump = m_indexBranch? nextID - m_indexBranch->GetEntries() : nextID; + if( m_indexBump < 0 ) { + // Seems this index is ahead of the master, cannot sync + m_indexBump = 0; + } } diff --git a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h index cfb09f21231186d206d321c896aec4d595faa309..b1f9984ecf070599026bc0678a8063fb72d383d0 100644 --- a/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h +++ b/Database/APR/RootStorageSvc/src/RootTreeIndexContainer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration * */ #ifndef POOL_ROOTTREEINDEXCONTAINER_H @@ -39,8 +39,14 @@ namespace pool { /// Standard destructor virtual ~RootTreeIndexContainer() {} + /// Open the container + virtual DbStatus open(DbDatabase&, const std::string&, const DbTypeInfo*, DbAccessMode) override final; + /// Number of entries within the container - virtual long long int nextRecordId(); + virtual long long int nextRecordId() override final; + + /// Suggest next Record ID for tbe next object written - for synced indexes + virtual void useNextRecordId(long long int) override final; /// Find object by object identifier and load it into memory /** @param ptr [IN/OUT] ROOT-style address of the pointer to object @@ -63,6 +69,11 @@ namespace pool { const int m_index_multi; /// Index (64 bit) long long int m_index; + + /// How much to increase nextRecordID to keep index values synced with other containers + long long int m_indexBump; }; } #endif //POOL_ROOTTREEINDEXCONTAINER_H + + diff --git a/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx b/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx index 2aaf732870c246ef9b23132dc5cab78142532a83..fc101270125c084f59f6926a7af6cbe22c4dd687 100644 --- a/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx +++ b/Database/APR/RootStorageSvc/test/branchContIdx_test.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ /** @@ -25,7 +25,9 @@ #include "StorageSvc/FileDescriptor.h" #include "StorageSvc/DbReflex.h" #include "StorageSvc/DbString.h" +#include "StorageSvc/DbOption.h" +using namespace pool; using namespace std; const string filename = "branchContIdx_testfile.root"; // test file name @@ -35,8 +37,9 @@ const string filename = "branchContIdx_testfile.root"; // test fil //const string containerNameB = "ContainerB"; // container for objects B // use branch containes -const string containerNameA = "Containers(A)"; // container for objects A -const string containerNameB = "Containers(B)"; // container for objects B +const string containerNameA = "Containers(A)"; // branch container for objects A +const string containerNameB = "Containers(B)"; // branch container for objects B +const string containerNameC = "ContainerC"; // tree container for objects C //const pool::DbType storageType = pool::ROOTTREE_StorageType; @@ -48,12 +51,19 @@ pool::DbString myStringA3("This is my string A3"); pool::DbString myStringA4("This is my string A4"); pool::DbString myStringA5("This is my string A5"); pool::DbString myStringA6("This is my string A6"); +pool::DbString myStringA7("This is my string A7"); pool::DbString myStringB1("This is my string B1"); pool::DbString myStringB2("This is my string B2"); +pool::DbString myStringB3("This is my string B3"); + +pool::DbString myStringC1("This is my string C1"); +pool::DbString myStringC2("This is my string C2"); +pool::DbString myStringC3("This is my string C3"); // string tokens to written objects, for use when reading back -string refA1, refA2, refA3, refA4, refA5, refA6, refB1, refB2; +string refA1, refA2, refA3, refA4, refA5, refA6, refA7; +string refB1, refB2, refB3, refC1, refC2, refC3; int main() { @@ -93,6 +103,18 @@ int main() { throw std::runtime_error( "Could not create a persistent shape." ); } + // Get IStorageExplorer IFace to set options + void *p = nullptr; + storSvc->queryInterface( IStorageExplorer::interfaceID(), &p ); + IStorageExplorer *storage = (IStorageExplorer*)p; + if( !storage ) { + throw std::runtime_error( "Failed to retrieve IStorageExplorer" ); + } + // Set container for master index (enables index synchronization between TTrees) + //DbOption masterIdxOpt("INDEX_MASTER", "", containerNameA.c_str()); + DbOption masterIdxOpt("INDEX_MASTER", "", "*"); + storage->setDatabaseOption(fd, masterIdxOpt); + // Commit here to test empty commits if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) { throw std::runtime_error( "Empty commit FAILED" ); @@ -106,26 +128,34 @@ int main() { } return token; }; + + auto Commit = [&](const int) { + if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) { + throw std::runtime_error( "Commit FAILED" ); + } + }; refA1 = writeStr(containerNameA, myStringA1)->toString(); refA2 = writeStr(containerNameA, myStringA2)->toString(); refA3 = writeStr(containerNameA, myStringA3)->toString(); refB1 = writeStr(containerNameB, myStringB1)->toString(); + refC1 = writeStr(containerNameC, myStringC1)->toString(); - // Commit - if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) { - throw std::runtime_error( "Commit FAILED" ); - } + Commit(1); refA4 = writeStr(containerNameA, myStringA4)->toString(); refB2 = writeStr(containerNameB, myStringB2)->toString(); + refC2 = writeStr(containerNameC, myStringC2)->toString(); refA5 = writeStr(containerNameA, myStringA5)->toString(); refA6 = writeStr(containerNameA, myStringA6)->toString(); - // Commit again - if( ! ( storSvc->endTransaction( connection, pool::Transaction::TRANSACT_COMMIT ).isSuccess() ) ) { - throw std::runtime_error( "Commit FAILED" ); - } + Commit(2); + + refA7 = writeStr(containerNameA, myStringA7)->toString(); + refC3 = writeStr(containerNameC, myStringC3)->toString(); + refB3 = writeStr(containerNameB, myStringB3)->toString(); + + Commit(3); // Close session if( !storSvc->disconnect( fd ).isSuccess() ) { @@ -147,6 +177,10 @@ int main() { cout << "Token for object A6 = " << refA6 << endl; cout << "Token for object B1 = " << refB1 << endl; cout << "Token for object B2 = " << refB2 << endl; + cout << "Token for object B3 = " << refB3 << endl; + cout << "Token for object C1 = " << refC1 << endl; + cout << "Token for object C2 = " << refC2 << endl; + cout << "Token for object C3 = " << refC3 << endl; // =============== READ back @@ -179,8 +213,13 @@ int main() { }; readfun(refA1); cout << "read back A1: " << readString << endl; + readfun(refA7); cout << "read back A7: " << readString << endl; + readfun(refC3); cout << "read back C3: " << readString << endl; readfun(refB1); cout << "read back B1: " << readString << endl; + readfun(refC2); cout << "read back C2: " << readString << endl; readfun(refA3); cout << "read back A3: " << readString << endl; + readfun(refC1); cout << "read back C1: " << readString << endl; + readfun(refB3); cout << "read back B3: " << readString << endl; readfun(refA6); cout << "read back A6: " << readString << endl; readfun(refA4); cout << "read back A4: " << readString << endl; readfun(refB2); cout << "read back B2: " << readString << endl; diff --git a/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h b/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h index d4f76404182999e7621f0f77d445a9ac19fb47ec..5e706f67be59fe3119e99fc5e2f89e7b73d628fc 100644 --- a/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h +++ b/Database/APR/StorageSvc/StorageSvc/DbContainerImp.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -118,8 +118,13 @@ namespace pool { virtual void setSections(const Sections& sections) { m_sections = sections; } /// Size of the container virtual long long int size(); + /// Get container name + virtual std::string name() const override + { return m_name; } /// Number of next record in the container (=size if no delete is allowed) virtual long long int nextRecordId(); + /// Suggest next Record ID for tbe next object written - used only with synced indexes + virtual void useNextRecordId(long long int) {}; /// Close the container and deallocate resources virtual DbStatus close(); diff --git a/Database/APR/StorageSvc/StorageSvc/DbDatabase.h b/Database/APR/StorageSvc/StorageSvc/DbDatabase.h index df17b9ea4b3e38cb3f5e82008b608cb8ae9697d2..1fe8d35f0e3b01029e5879827fc068a69266988e 100644 --- a/Database/APR/StorageSvc/StorageSvc/DbDatabase.h +++ b/Database/APR/StorageSvc/StorageSvc/DbDatabase.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -190,8 +190,8 @@ namespace pool { /// Access local container token (if container exists) const Token* cntToken(const std::string& cntName); /// Allow access to all known containers - DbStatus containers(std::vector<const Token*>& conts, - bool intern=false); + DbStatus containers(std::vector<const Token*>& conts, bool intern=false); + DbStatus containers(std::vector<IDbContainer*>& conts, bool intern=false); /// Allow access to all known associations between containers DbStatus associations(std::vector<const Token*>& assocs); /// Allow access to all known shapes used by the database diff --git a/Database/APR/StorageSvc/StorageSvc/IDbContainer.h b/Database/APR/StorageSvc/StorageSvc/IDbContainer.h index b1b70fd9b22a38a6a07257a478c65f6c53af2015..5f993ac03cb1f7ceea99f3f00753405b1b725b37 100644 --- a/Database/APR/StorageSvc/StorageSvc/IDbContainer.h +++ b/Database/APR/StorageSvc/StorageSvc/IDbContainer.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ // $Id: IDbContainer.h 726071 2016-02-25 09:23:05Z krasznaa $ @@ -58,6 +58,8 @@ namespace pool { virtual void release() = 0; /// Access to container size virtual long long int size() = 0; + /// Get container name + virtual std::string name() const = 0; /// Ask if a given shape is supported virtual DbStatus isShapeSupported(const DbTypeInfo* typ) const = 0; /// Set options @@ -79,6 +81,8 @@ namespace pool { /// Number of next record in the container (=size if no delete is allowed) virtual long long int nextRecordId() = 0; + /// Suggest next Record ID for tbe next object written - used only with synced indexes + virtual void useNextRecordId(long long int) = 0; /// Close the container virtual DbStatus close() = 0; diff --git a/Database/APR/StorageSvc/StorageSvc/Transaction.h b/Database/APR/StorageSvc/StorageSvc/Transaction.h index 6a0de763e1bfba13775bb16a8fd5eec004f456df..6f840602217a9a8dbe0090e0a28cf6ca9a0bd39a 100644 --- a/Database/APR/StorageSvc/StorageSvc/Transaction.h +++ b/Database/APR/StorageSvc/StorageSvc/Transaction.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -65,6 +65,10 @@ namespace pool { virtual Action state() const = 0; /// Access to the transaction type virtual Type type() const = 0; + + /// Translate Action to string + static const char* actionAsString(Action action); + }; } // End namespace pool #endif // POOL_TRANSACTION_H diff --git a/Database/APR/StorageSvc/StorageSvc/pool.h b/Database/APR/StorageSvc/StorageSvc/pool.h index b8a6a5f3d91cf44116bf78687823eb0694cda211..6f279a00293e16c43d1a2280231fdf8e4e4875ee 100644 --- a/Database/APR/StorageSvc/StorageSvc/pool.h +++ b/Database/APR/StorageSvc/StorageSvc/pool.h @@ -2,7 +2,6 @@ Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ -// $Id: pool.h 590734 2014-04-01 21:49:36Z gemmeren $ //==================================================================== // // Package : StorageSvc (The pool framework) @@ -96,7 +95,7 @@ namespace pool { /// Check for tracing bool doTrace(); - /// Translate acce mode to string + /// Translate access mode to string const char* accessMode(pool::DbAccessMode access_mode); /// Delete a pointer diff --git a/Database/APR/StorageSvc/src/DbDatabase.cpp b/Database/APR/StorageSvc/src/DbDatabase.cpp index b9175480d602a0ef7c002ca1f1342cbc2cfd1fb3..9310ca26a31cf1734181cc49fdaf3a5bfb89c6f6 100644 --- a/Database/APR/StorageSvc/src/DbDatabase.cpp +++ b/Database/APR/StorageSvc/src/DbDatabase.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -206,6 +206,10 @@ const Token* DbDatabase::cntToken(const string& cntName) DbStatus DbDatabase::containers(vector<const Token*>& conts,bool with_internal) { return isValid() ? ptr()->containers(conts,with_internal) : Error; } +/// Allow access to all known containers +DbStatus DbDatabase::containers(vector<IDbContainer*>& conts,bool with_internal) +{ return isValid() ? ptr()->containers(conts,with_internal) : Error; } + /// Allow access to all known associations between containers DbStatus DbDatabase::associations(vector<const Token*>& assocs) { return isValid() ? ptr()->associations(assocs) : Error; } diff --git a/Database/APR/StorageSvc/src/DbDatabaseObj.cpp b/Database/APR/StorageSvc/src/DbDatabaseObj.cpp index af959406746f5a365b255440c9ec0d6ab5ab0b12..a99121100f2657f3e08211031ef4e2b863ede456 100644 --- a/Database/APR/StorageSvc/src/DbDatabaseObj.cpp +++ b/Database/APR/StorageSvc/src/DbDatabaseObj.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -24,6 +24,7 @@ #include "StorageSvc/DbReflex.h" #include "StorageSvc/DbColumn.h" #include "StorageSvc/DbTypeInfo.h" +#include "StorageSvc/DbOption.h" #include "StorageSvc/IOODatabase.h" #include "StorageSvc/IDbDatabase.h" #include "StorageSvc/IDbContainer.h" @@ -863,6 +864,23 @@ DbStatus DbDatabaseObj::containers(vector<const Token*>& conts,bool with_interna return Error; } +/// Allow access to all known containers +DbStatus DbDatabaseObj::containers(vector<IDbContainer*>& conts,bool with_internals) { + conts.clear(); + if ( 0 == m_info ) open(); + if ( 0 != m_info ) { + for (iterator i=begin(); i != end(); ++i ) { + DbContainerObj* c = (*i).second; + if( c == m_links.ptr() || c == m_params.ptr() || c == m_shapes.ptr() ) + if( not with_internals) continue; + if( c->info() ) conts.push_back( c->info() ); + } + return Success; + } + return Error; +} + + /// Access local container token (if container exists) const Token* DbDatabaseObj::cntToken(const string& cntName) { if ( 0 == m_info ) open(); diff --git a/Database/APR/StorageSvc/src/DbDatabaseObj.h b/Database/APR/StorageSvc/src/DbDatabaseObj.h index 46765b73d85cf5e130f81a81378e000b00057d1f..27b43ac8920fc91a2a5e5113c991a3de34e78eb9 100644 --- a/Database/APR/StorageSvc/src/DbDatabaseObj.h +++ b/Database/APR/StorageSvc/src/DbDatabaseObj.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ //==================================================================== @@ -72,6 +72,9 @@ namespace pool { typedef std::map< Guid , const DbTypeInfo* > ShapeMap; /// Definition of map with index elements typedef std::map< long long int , int > IndexMap; + /// Base class convenience typdef + typedef DbAccessObj<std::string, DbContainerObj > Base; + /// Handle to domain DbDomain m_dom; /// Handle to link container @@ -171,8 +174,8 @@ namespace pool { /// Access local container token (if container exists) const Token* cntToken(const std::string& cntName); /// Allow access to all known containers - DbStatus containers(std::vector<const Token*>& conts, - bool intern); + DbStatus containers(std::vector<const Token*>& conts, bool intern); + DbStatus containers(std::vector<IDbContainer*>& conts, bool intern); /// Allow access to all known associations between containers DbStatus associations(std::vector<const Token*>& conts); /// Allow access to all known shapes used by the database diff --git a/Database/APR/StorageSvc/src/Transaction.cpp b/Database/APR/StorageSvc/src/Transaction.cpp index b244402651990816abbcfca4959d749abd1d320c..532452bb14a366872c90242f7462ff91c563c155 100644 --- a/Database/APR/StorageSvc/src/Transaction.cpp +++ b/Database/APR/StorageSvc/src/Transaction.cpp @@ -1,8 +1,7 @@ /* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ -// $Header: /cvs/PF/pool/StorageSvc/src/Transaction.cpp,v 1.7 2007/11/20 16:43:10 frankb Exp $ // ==================================================================== // Transaction.cpp // -------------------------------------------------------------------- @@ -30,3 +29,16 @@ Transaction& Transaction::operator=(const Transaction& c) { bool Transaction::operator==(const Transaction& /* c */ ) const { return false; } + +/// Translate Action to string +const char* Transaction::actionAsString(Action action) { + switch(action) { + case TRANSACT_START : return "START"; + case TRANSACT_ACTIVE : return "ACTIVE"; + case TRANSACT_COMMIT : return "COMMIT"; + case TRANSACT_FLUSH : return "FLUSH"; + case TRANSACT_ROLLBACK : return "ROLLBACK"; + case TRANSACT_ENDED : return "ENDED"; + } + return "UNDEFINED"; +} diff --git a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx index c11b00f8cbac78f8a7fa05ae1e88ceac9d6d9761..125635fd87ada22ac6da3ff387f342f04b9cfbfa 100644 --- a/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx +++ b/Database/AthenaPOOL/PoolSvc/src/PoolSvc.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ /** @file PoolSvc.cxx @@ -49,6 +49,11 @@ #include <cstring> // for strcmp() #include <sys/stat.h> // for struct stat #include <algorithm> // for STL find() +#include <ctype.h> + +bool isNumber(const std::string& s) { + return !s.empty() and ( isdigit(s[0]) or s[0]=='+' or s[0]=='-' ); +} //__________________________________________________________________________ StatusCode PoolSvc::initialize() { @@ -836,7 +841,9 @@ StatusCode PoolSvc::setAttribute(const std::string& optName, return(StatusCode::FAILURE); } } - if (data[data.size() - 1] == 'L') { + if( !isNumber(data) ) { + retError = dbH->technologySpecificAttributes().setAttribute(optName, data.c_str(), objName); + } else if( data[data.size() - 1] == 'L' ) { retError = dbH->technologySpecificAttributes().setAttribute<long long int>(optName, atoll(data.c_str()), objName); } else { retError = dbH->technologySpecificAttributes().setAttribute<int>(optName, atoi(data.c_str()), objName);