| The Gaudi Framework v27r1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

RegistryEntry.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RegistryEntry.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : DataSvc ( The LHCb Offline System)
6 //
7 // Description: implementation of the Transient data store
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 29/10/98| Initial version | MF
15 // | 03/02/99| Protect dynamic_cast with try-catch clauses | MF
16 // +---------+----------------------------------------------+---------
17 //
18 //====================================================================
19 #define DATASVC_REGISTRYENTRY_CPP
20
21 // STL include files
22 #include <algorithm>
23
24 // Interfaces
25 #include "GaudiKernel/IDataStoreAgent.h"
26 #include "GaudiKernel/IOpaqueAddress.h"
27
28 // Framework include files
29 #include "GaudiKernel/DataObject.h"
30 #include "GaudiKernel/RegistryEntry.h"
31
32
33 // If you absolutely need optimization: switch off dynamic_cast.
34 // This improves access to the data store roughly by more than 10 %
35 // for balanced trees.
36 //
37 // M.Frank
38 //
39 #define CAST_REGENTRY(x,y) dynamic_cast<x>(y)
40 //#define CAST_REGENTRY(x,y) (x)(y)
41 constexpr char SEPARATOR { '/' };
42
44 DataSvcHelpers::RegistryEntry::RegistryEntry(std::string path, RegistryEntry* parent) :
45 m_path(std::move(path)),
46 m_pParent(parent)
47 {
48 std::string::size_type sep = m_path.rfind(SEPARATOR);
49 if ( m_path.front() != SEPARATOR ) m_path.insert(0,1,SEPARATOR);
50 if ( sep != std::string::npos ) m_path.erase(0,sep);
51 assemblePath(m_fullpath);
52 addRef();
53 }
54
56 DataSvcHelpers::RegistryEntry::~RegistryEntry() {
57 deleteElements();
58 if ( m_pObject ) {
59 if ( !m_isSoft ) m_pObject->setRegistry(nullptr);
60 m_pObject->release();
61 }
62 if ( m_pAddress ) {
63 if ( !m_isSoft ) m_pAddress->setRegistry(nullptr);
64 m_pAddress->release();
65 }
66 }
67
69 unsigned long DataSvcHelpers::RegistryEntry::release() {
70 unsigned long cnt = --m_refCount;
71 if ( !m_refCount ) delete this;
72 return cnt;
73 }
74
76 void DataSvcHelpers::RegistryEntry::setParent(RegistryEntry* pParent) {
77 m_pParent = pParent;
78 m_fullpath.clear();
79 assemblePath(m_fullpath);
80 }
81
83 void DataSvcHelpers::RegistryEntry::makeSoft(DataObject* pObject) {
84 m_isSoft = true;
85 setObject(pObject);
86 // if ( 0 != m_pObject ) { // Useless: This justs sets my own address again...
87 // setAddress(m_pObject->address());
88 // }
89 }
90
92 void DataSvcHelpers::RegistryEntry::makeSoft(IOpaqueAddress* pAddress) {
93 m_isSoft = true;
94 setAddress(pAddress);
95 }
96
98 void DataSvcHelpers::RegistryEntry::makeHard(DataObject* pObject) {
99 makeSoft(pObject);
100 m_isSoft = false;
101 if ( m_pObject ) m_pObject->setRegistry(this);
102 if ( m_pAddress ) m_pAddress->setRegistry(this);
103 }
104
106 void DataSvcHelpers::RegistryEntry::makeHard(IOpaqueAddress* pAddress) {
107 m_isSoft = false;
108 setAddress(pAddress);
109 }
110
112 void DataSvcHelpers::RegistryEntry::setAddress( IOpaqueAddress* pAddress ) {
113 if ( pAddress ) {
114 pAddress->addRef();
115 pAddress->setRegistry(this);
116 }
117 if ( m_pAddress ) m_pAddress->release();
118 m_pAddress = pAddress;
119 }
120
122 void DataSvcHelpers::RegistryEntry::setObject( DataObject* pObject ) {
123 if ( pObject ) {
124 pObject->addRef();
125 if ( !isSoft() ) pObject->setRegistry(this);
126 }
127 if ( m_pObject ) m_pObject->release();
128 m_pObject = pObject;
129 }
130
132 long DataSvcHelpers::RegistryEntry::remove ( IRegistry* obj ) {
133 try {
134 RegistryEntry* pEntry = dynamic_cast<RegistryEntry*>(obj);
135 auto i = std::remove(std::begin(m_store), std::end(m_store), pEntry);
136 if (i != std::end(m_store)) {
137 pEntry->release();
138 m_store.erase( i, std::end(m_store) );
139 }
140 }
141 catch ( ... ) { }
142 return m_store.size();
143 }
144
146 long DataSvcHelpers::RegistryEntry::remove ( const std::string& nam ) {
147 if ( nam.front() != SEPARATOR ) return remove( SEPARATOR+nam );
148 // if this object is already present, this is an error....
149 for (auto& i : m_store ) {
150 if ( nam == i->name() ) {
151 remove(i);
152 return StatusCode::SUCCESS;
153 }
154 }
155 return StatusCode::FAILURE;
156 }
157
159 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_create(std::string nam) {
160 if ( nam.front() != SEPARATOR ) nam.insert(0,1,SEPARATOR);
161 // if this object is already present, this is an error....
162 auto not_present = std::none_of( std::begin(m_store), std::end(m_store),
163 [&](IRegistry* i) { return nam == i->name();
164 } );
165 return not_present ? new RegistryEntry( std::move(nam), this ) : nullptr;
166 }
167
169 long DataSvcHelpers::RegistryEntry::add( IRegistry* obj ) {
170 RegistryEntry* pEntry = CAST_REGENTRY(RegistryEntry*, obj);
171 return i_add(pEntry);
172 }
173
175 long DataSvcHelpers::RegistryEntry::i_add( RegistryEntry* pEntry ) {
176 //TODO: if this is the sole place where items are added to m_store,
177 // and we know here that they must be RegisteryEntry, can we
178 // drop the dynamic_cast every where else???
179 //TODO: if so, can we also change m_store to be std::vector<RegistryEntry*>
180 // instead
181 //TODO: if so, can we not make it std::vector<RegistryEntry> instead?
182 //TODO: if so, should make sure that a RegistryEntry can be std::move'ed
183 try {
184 pEntry->setDataSvc(m_pDataProviderSvc);
185 m_store.push_back(pEntry);
186 pEntry->setParent(this);
187 if ( !pEntry->isSoft() && pEntry->address() ) {
188 pEntry->address()->setRegistry(pEntry);
189 }
190 }
191 catch ( ... ) {
192 }
193 return m_store.size();
194 }
195
197 long DataSvcHelpers::RegistryEntry::add ( const std::string& name, DataObject* pObject, bool is_soft ) {
198 RegistryEntry* entry = i_create(name);
199 if ( !entry ) return StatusCode::FAILURE;
200 ( is_soft ) ? entry->makeSoft(pObject) : entry->makeHard(pObject);
201 i_add( entry );
202 return StatusCode::SUCCESS;
203 }
204
206 long DataSvcHelpers::RegistryEntry::add ( const std::string& name, IOpaqueAddress* pAddress, bool is_soft ) {
207 RegistryEntry* entry = i_create(name);
208 if ( !entry ) return StatusCode::FAILURE;
209 ( is_soft ) ? entry->makeSoft(pAddress) : entry->makeHard(pAddress);
210 i_add( entry );
211 return StatusCode::SUCCESS;
212 }
213
215 long DataSvcHelpers::RegistryEntry::deleteElements() {
216 for (auto& i : m_store ) {
217 RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, i);
218 if ( entry ) {
219 entry->deleteElements();
220 entry->release();
221 }
222 }
223 m_store.erase(m_store.begin(), m_store.end());
224 return 0;
225 }
226
228 IRegistry* DataSvcHelpers::RegistryEntry::i_find( const IRegistry* obj ) const {
229 auto i = std::find(m_store.begin(),m_store.end(),obj);
230 return (i!=m_store.end()) ? (*i) : nullptr;
231 }
232
234 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(boost::string_ref path) const {
235 if ( path.front() == SEPARATOR ) path.remove_prefix(1); // strip leading '/', if present
236 while (!path.empty()) {
237 // check that the chars of path prior to / are the same as regEnt->name()
238 // (i.e. match { nam:"/Ab" path:"/Ab/C"}
239 // but not { nam:"/Abc" path:"/Ab/C"})
240 auto loc1 = path.find(SEPARATOR);
241 auto cpath = path.substr(0,loc1);
242 if (loc1 != boost::string_ref::npos) {
243 path.remove_prefix(loc1+1);
244 } else {
245 path.clear();
246 }
247 auto i = std::find_if( std::begin(m_store), std::end(m_store),
248 [&](decltype(m_store)::const_reference reg) {
249 return cpath == boost::string_ref{reg->name()}.substr(1);
250 });
251 if ( i!=std::end(m_store) ) {
252 RegistryEntry* regEnt = CAST_REGENTRY(RegistryEntry*, *i);
253 return path.empty() ? regEnt : regEnt->i_find(path);
254 }
255 // If this node is "/NodeA", this part allows to find "/NodeA/NodeB" as
256 // our "/NodeB" child.
257 if ( cpath != boost::string_ref{m_path}.substr(1) ) break;
258 }
259 return nullptr;
260 }
261
263 DataSvcHelpers::RegistryEntry* DataSvcHelpers::RegistryEntry::i_find(const DataObject* key) const {
264 if ( key ) {
265 if ( key == m_pObject ) {
266 return const_cast<RegistryEntry*>(this);
267 }
268 // Look in the immediate level:
269 RegistryEntry *result = CAST_REGENTRY(RegistryEntry*, i_find(key->registry()));
270 if ( result ) return result;
271 // Go levels down
272 for (const auto& i : m_store) {
273 try {
274 const RegistryEntry *entry = CAST_REGENTRY(RegistryEntry*, i);
275 result = entry->i_find(key);
276 if( result ) return result;
277 }
278 catch ( ... ) { }
279 }
280 }
281 return nullptr;
282 }
283
284 // Traverse registry tree
285 long DataSvcHelpers::RegistryEntry::traverseTree(IDataStoreAgent* pAgent, int level) {
286 bool go_down = pAgent->analyse(this, level);
287 long status = StatusCode::SUCCESS;
288 if ( go_down ) {
289 for ( auto& i : m_store ) {
290 try {
291 RegistryEntry* entry = CAST_REGENTRY(RegistryEntry*, i);
292 entry->traverseTree(pAgent, level+1);
293 }
294 catch (...) {
295 status = StatusCode::FAILURE;
296 }
297 }
298 }
299 return status;
300 }
301
302 // Recursive helper to assemble the full path name of the entry
303 void DataSvcHelpers::RegistryEntry::assemblePath(std::string& buffer) const {
304 if ( m_pParent ) m_pParent->assemblePath(buffer);
305 buffer += m_path;
306 }
DataSvcHelpers::RegistryEntry::deleteElements
virtual long deleteElements()
Delete all contained elements.
Definition: RegistryEntry.cpp:215
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:28
SEPARATOR
constexpr char SEPARATOR
Definition: RegistryEntry.cpp:41
std::string::front
T front(T...args)
IDataStoreAgent::analyse
virtual bool analyse(IRegistry *pObject, int level)=0
Analyse the data object.
DataSvcHelpers::RegistryEntry::addRef
unsigned long addRef() override
IInterface implementation: Dereference the object.
Definition: RegistryEntry.h:118
DataSvcHelpers::RegistryEntry::add
virtual long add(const std::string &name, DataObject *pObject, bool is_soft=false)
Add entry to data store.
Definition: RegistryEntry.cpp:197
std::string::rfind
T rfind(T...args)
DataSvcHelpers::RegistryEntry::traverseTree
virtual long traverseTree(IDataStoreAgent *pAgent, int level=0)
traverse data tree
Definition: RegistryEntry.cpp:285
DataSvcHelpers::RegistryEntry::~RegistryEntry
~RegistryEntry() override
Standard Destructor.
Definition: RegistryEntry.cpp:56
std
STL namespace.
DataObject::setRegistry
void setRegistry(IRegistry *pRegistry)
Set pointer to Registry.
Definition: DataObject.h:70
DataSvcHelpers::RegistryEntry::release
unsigned long release() override
IInterface implementation: Reference the object.
Definition: RegistryEntry.cpp:69
CAST_REGENTRY
#define CAST_REGENTRY(x, y)
Definition: RegistryEntry.cpp:39
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
std::end
T end(T...args)
DataSvcHelpers::RegistryEntry::remove
virtual long remove(const std::string &name)
Remove an entry from the store.
Definition: RegistryEntry.cpp:146
std::remove
T remove(T...args)
DataSvcHelpers::RegistryEntry::setAddress
void setAddress(IOpaqueAddress *pAddress) override
Set/Update Opaque address.
Definition: RegistryEntry.cpp:112
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:74
DataSvcHelpers::RegistryEntry::i_add
long i_add(RegistryEntry *entry)
Internal method to add entries.
Definition: RegistryEntry.cpp:175
std::string
STL class.
DataSvcHelpers::RegistryEntry::m_fullpath
std::string m_fullpath
String containing full path of the object (volatile)
Definition: RegistryEntry.h:52
DataSvcHelpers::RegistryEntry::assemblePath
void assemblePath(std::string &buffer) const
The following entries serve two aspects: 1) They are faster for recursive calls, because they are non...
Definition: RegistryEntry.cpp:303
DataSvcHelpers::RegistryEntry::isSoft
virtual bool isSoft() const
Is the link soft or hard.
Definition: RegistryEntry.h:146
DataSvcHelpers::RegistryEntry::setParent
void setParent(RegistryEntry *pParent)
Set new parent pointer.
Definition: RegistryEntry.cpp:76
DataObject::addRef
virtual unsigned long addRef()
Add reference to object.
Definition: DataObject.cpp:63
DataSvcHelpers::RegistryEntry::setObject
void setObject(DataObject *obj)
Set/Update object address.
Definition: RegistryEntry.cpp:122
DataSvcHelpers::RegistryEntry::address
IOpaqueAddress * address() const override
Retrieve opaque storage address.
Definition: RegistryEntry.h:138
StatusCode::FAILURE
Definition: StatusCode.h:29
StatusCode::SUCCESS
Definition: StatusCode.h:30
std::string::erase
T erase(T...args)
DataSvcHelpers::RegistryEntry::setDataSvc
void setDataSvc(IDataProviderSvc *s)
Set the transient data store.
Definition: RegistryEntry.h:87
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
DataSvcHelpers::RegistryEntry::makeSoft
void makeSoft(DataObject *pObject)
Initialize link as soft link.
Definition: RegistryEntry.cpp:83
DataSvcHelpers::RegistryEntry::i_create
RegistryEntry * i_create(std::string name)
Internal method to create entries.
Definition: RegistryEntry.cpp:159
IDataStoreAgent.h
std::move
T move(T...args)
Gaudi::Utils::Histos::path
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
Definition: HistoTableFormat.cpp:191
IOpaqueAddress.h
RegistryEntry.h
DataSvcHelpers::RegistryEntry
Definition of an entry in the transient data store.
Definition: RegistryEntry.h:36
std::string::insert
T insert(T...args)
std::find
T find(T...args)
IDataStoreAgent
Generic data agent interface.
Definition: IDataStoreAgent.h:16
std::begin
T begin(T...args)
std::none_of
T none_of(T...args)
DataSvcHelpers::RegistryEntry::RegistryEntry
RegistryEntry(std::string path, RegistryEntry *parent=nullptr)
Standard Constructor.
Definition: RegistryEntry.cpp:44
DataSvcHelpers::RegistryEntry::m_path
std::string m_path
Path name.
Definition: RegistryEntry.h:54
gaudirun.level
level
Definition: gaudirun.py:261
IOpaqueAddress::setRegistry
virtual void setRegistry(IRegistry *r)=0
Update directory pointer.
IOpaqueAddress
Opaque address interface definition.
Definition: IOpaqueAddress.h:23
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
ana.i
list i
Definition: ana.py:128
DataSvcHelpers::RegistryEntry::i_find
IRegistry * i_find(const IRegistry *pDirectory) const
Internal method to retrieve data directory.
Definition: RegistryEntry.cpp:228
DataObject.h
IOpaqueAddress::addRef
virtual unsigned long addRef()=0
Add reference to object.
DataSvcHelpers::RegistryEntry::makeHard
void makeHard(DataObject *pObject)
Initialize link as hard link.
Definition: RegistryEntry.cpp:98