00001 #include "PoolClasses.h"
00002
00003
00004
00005 namespace Gaudi {
00006
00007
00017 class PoolTool : virtual public RootDataConnection::Tool {
00019 std::vector<Gaudi::RootRef> m_poolLinks;
00020
00021 public:
00023 PoolTool(RootDataConnection* con) { c = con; }
00024
00026 string _treeName(string t) {
00027 for(string::iterator j = t.begin(); j != t.end(); ++j )
00028 if ( *j == '/' ) *j = '_';
00029 return t;
00030 }
00031
00032 virtual RootRef poolRef(size_t i) const { return m_poolLinks[i]; }
00033
00035 virtual int loadRefs(CSTR , CSTR cnt, unsigned long entry, RootObjectRefs& refs) {
00036 TTree* t = sections()[cnt];
00037 if ( !t ) {
00038 t = (TTree*)c->file()->Get(_treeName(cnt).c_str());
00039 }
00040 if ( t ) {
00041 TBranch* b1 = t->GetBranch("Links");
00042 TBranch* b2 = t->GetBranch("Refs");
00043 MsgStream& msg = msgSvc();
00044 if ( b1 && b2 ) {
00045 LinkManager lm, *plm = &lm;
00046 PoolDbLinkManager mgr, *pmgr = &mgr;
00047 b1->SetAutoDelete(kFALSE);
00048 b2->SetAutoDelete(kFALSE);
00049 b1->SetAddress(&plm);
00050 b2->SetAddress(&pmgr);
00051 int nb1 = b1->GetEvent(entry);
00052 int nb2 = b2->GetEvent(entry);
00053 if ( nb1>1 && nb2>1 ) {
00054 size_t ref_size = mgr.references().size();
00055 refs.refs.resize(ref_size);
00056 msg << MSG::VERBOSE;
00057 for(size_t j = 0; j < ref_size; ++j) {
00058 const pair<int, int>& oid = mgr.references()[j]->m_oid;
00059 string loc = mgr.links()[j].substr(1);
00060 RootRef& r = refs.refs[j];
00061 if ( oid.first>=0 ) {
00062 r = m_poolLinks[oid.first];
00063 r.entry = oid.second;
00064 r.link = c->makeLink(loc);
00065 msg << "Add leaf:" << oid.first << "->" << loc << " from " << c->getDb(r.dbase)
00066 << "#" << c->getCont(r.container)
00067 << " Link:" << c->getLink(r.link)
00068 << " CLID:" << hex << r.clid
00069 << " Typ:" << hex << int(r.svc)
00070 << " Ent:" << dec << r.entry << endl;
00071 }
00072 }
00073 for(int i = 0, n=lm.size(); i < n; ++i) {
00074 LinkManager::Link* lnk = lm.link(i);
00075 int link_id = c->makeLink(lnk->path());
00076 msg << "Add Link:" << lnk->path() << endl;
00077 refs.links.push_back(link_id);
00078 }
00079 return nb1 + nb2;
00080 }
00081 }
00082 msg << MSG::ERROR << "Failed to access POOL Ref/Link branches:" << cnt
00083 << " [" << _treeName(cnt) << "]" << endmsg;
00084 t->Print();
00085 }
00086 return -1;
00087 }
00088
00090 virtual TBranch* getBranch(CSTR , CSTR branch_name) {
00091 TTree* t = sections()[branch_name];
00092 if ( t ) {
00093 return (TBranch*)t->GetListOfBranches()->At(0);
00094 }
00095 string tname = _treeName(branch_name);
00096 t = (TTree*)c->file()->Get(tname.c_str());
00097 if ( t ) {
00098 TBranch* b = (TBranch*)t->GetListOfBranches()->At(0);
00099 if ( b ) {
00100 sections()[branch_name] = t;
00101 return b;
00102 }
00103 msgSvc() << MSG::ERROR << "Failed to access POOL branch:"
00104 << branch_name << " [" << tname << "]" << endmsg;
00105 t->Print();
00106 }
00107 return 0;
00108 }
00109
00111 virtual StatusCode saveRefs() { return StatusCode::FAILURE; }
00112
00114 StatusCode readRefs() {
00115 int i;
00116 char text[2048];
00117 msgSvc() << MSG::VERBOSE;
00118
00119
00120 TTree* t = (TTree*)c->file()->Get("##Params");
00121 if ( 0 == t ) {
00122 return StatusCode::FAILURE;
00123 }
00124 TBranch* b = t->GetBranch("db_string");
00125 if ( 0 == b ) {
00126 return StatusCode::FAILURE;
00127 }
00128 for(i=0,b->SetAddress(text); i < b->GetEntries(); ++i) {
00129 b->GetEvent(i);
00130 char* id1 = strstr(text,"[NAME=");
00131 char* id2 = strstr(text,"[VALUE=");
00132 if ( id1 && id2 ) {
00133 id1 += 6;
00134 id2 += 7;
00135 char* id11 = strstr(id1, "]");
00136 char* id22 = strstr(id2, "]");
00137 if ( id11 && id22 ) {
00138 *id11 = 0;
00139 *id22 = 0;
00140 params().push_back(make_pair(id1,id2));
00141 msgSvc() << "Param:" << id1 << "=" << id2 << "." << endmsg;
00142 }
00143 }
00144 }
00145
00146
00147 t = (TTree*)c->file()->Get("##Links");
00148 if ( 0 == t ) {
00149 return StatusCode::FAILURE;
00150 }
00151 b = t->GetBranch("db_string");
00152 if ( 0 == b ) {
00153 return StatusCode::FAILURE;
00154 }
00155 m_poolLinks.resize((size_t)b->GetEntries()+2);
00156 for(i=0,b->SetAddress(text); i < b->GetEntries(); ++i) {
00157 b->GetEvent(i);
00158 std::string db, container;
00159 int clid = 1, technology = 0, ipar[2] = {-1,-1};
00160 for(char* p1 = (char*)text; p1; p1 = ::strchr(++p1,'[')) {
00161 char* p2 = ::strchr(p1, '=');
00162 char* p3 = ::strchr(p1, ']');
00163 if ( p2 && p3 ) {
00164 if ( ::strncmp("[DB=", p1, 4) == 0 ) {
00165 *p3 = 0;
00166 db = p1+4;
00167 }
00168 else if ( ::strncmp("[CNT=", p1, 5) == 0 ) {
00169 *p3 = 0;
00170 container = p1+5;
00171 }
00172 else if ( ::strncmp("[OID=", p1, 5) == 0 ) {
00173 *p3 = 0;
00174 ::sscanf(p1+5,"%08X,%08X",&ipar[0],&ipar[1]);
00175 }
00176 else if ( ::strncmp("[CLID=", p1, 6) == 0 ) {
00177 *p3 = 0;
00178 ::sscanf(p1+6,"%08X",&clid);
00179 }
00180 else if ( ::strncmp("[TECH=", p1, 6) == 0 ) {
00181 *p3 = 0;
00182 ::sscanf(p1+6,"%08X",&technology);
00183 }
00184 else {
00185 *p3 = *p2 = 0;
00186 }
00187 *p3 = ']';
00188 *p2 = '=';
00189 }
00190 }
00191 c->makeRef("",clid,technology,db,container,-1,m_poolLinks[i+2]);
00192 RootRef& r = m_poolLinks[i];
00193 msgSvc() << "Add link[" << i << "]:" << db << container << " [" << r.dbase << "," << r.container << "] "
00194 << " tech:" << hex << setw(8) << r.svc << " CLID:" << setw(8) << r.clid << dec << endmsg;
00195 }
00196 return StatusCode::SUCCESS;
00197 }
00198 };
00199 }