EventAnalysis  1.3.0
DataStore.hpp
Go to the documentation of this file.
1 /*
2  * DataStore.hpp
3  *
4  * Created on: 14 Dec 2017
5  * Author: Nicola Mori
6  */
7 
8 #ifndef DATASTORE_HPP_
9 #define DATASTORE_HPP_
10 
11 #include "utils/StringUtils.h"
12 
13 namespace EA {
14 template <class DataType>
15 void DataStore::AddObject(const std::string &name, DataType &obj, const observer_ptr<ObjectProducer> &producer) {
16  InsertionResult ir = ObjectMap::AddObject(name, obj);
17  if (ir != InsertionResult::SUCCESS) {
18  THROW_INSERTION_EXC(ir, name);
19  }
20  if (producer && _remObjTracker) {
21  if (!(_remObjTracker->TrackObject(name, producer))) {
23  throw Insertion::Error("Can't track object \"" + name + "\"");
24  }
25  }
26 }
27 
28 template <class DataType>
29 void DataStore::AddObject(const std::string &name, observer_ptr<DataType> obj,
30  const observer_ptr<ObjectProducer> &producer) {
31  InsertionResult ir = ObjectMap::AddObject(name, obj);
32  if (ir != InsertionResult::SUCCESS) {
33  THROW_INSERTION_EXC(ir, name);
34  }
35  if (producer && _remObjTracker) {
36  if (!(_remObjTracker->TrackObject(name, producer))) {
38  throw Insertion::Error("Can't track object \"" + name + "\"");
39  }
40  }
41 }
42 
43 template <class DataType>
44 void DataStore::AddObject(const std::string &name, std::shared_ptr<DataType> obj,
45  const observer_ptr<ObjectProducer> &producer) {
46  InsertionResult ir = ObjectMap::AddObject(name, obj);
47  if (ir != InsertionResult::SUCCESS) {
48  THROW_INSERTION_EXC(ir, name);
49  }
50  if (producer && _remObjTracker) {
51  if (!(_remObjTracker->TrackObject(name, producer))) {
53  throw Insertion::Error("Can't track object \"" + name + "\"");
54  }
55  }
56 }
57 
58 template <class DataType>
59 void DataStore::AddObject(const std::string &name, std::unique_ptr<DataType> obj,
61  InsertionResult ir = ObjectMap::AddObject(name, std::move(obj));
62  if (ir != InsertionResult::SUCCESS) {
63  THROW_INSERTION_EXC(ir, name);
64  }
65 }
66 
67 template <class DataType> observer_ptr<DataType> DataStore::GetObject(const std::string &name) {
68 
69  // Retrieval of an object. The object will be fetched from the store and
70  // from the data providers (if they exist) in this order.
71  // The retrieve result is the best result obtained in the above steps.
72 
73  // 1. Try to retrieve the requested object from existing ones
74  auto obj = GetFromMap<DataType>(name);
75  if (obj.GetRetrievalResult() == RetrievalResult::SUCCESS) {
76  return obj;
77  }
78 
79  // 2. Try to retrieve the requested object from a registered provider
80  ObjectWrapper w;
81  RetrievalResult result = obj.GetRetrievalResult();
82  // Insert the desired type into the wrapper
83  w = (DataType *)(nullptr);
84  // Retrieve from the provider
85  std::string actualName;
87  result = std::max(GetFromProvider(name, w, actualName, provider), result);
88 
89  // 3. Check the type if the object has been found.
90  if (result == RetrievalResult::SUCCESS) {
91  auto objAfterCast = CastAndWrap<DataType>(name, actualName, std::move(w), provider);
92  if (!objAfterCast) {
93  THROW_RETRIEVAL_EXC(objAfterCast.GetRetrievalResult(), name);
94  }
95  return objAfterCast;
96  } else {
97  if (result == RetrievalResult::NOTFOUND) {
98  // The object is not found in data providers, so let's see if it is produced by an algorithm to eventually
99  // return NOTAVAILABLE.
100  if (IsAlgoProducedObject(name)) {
101  throw Retrieval::NotAvailable("Object \"" + name + "\" is not available");
102  }
103  }
104  THROW_RETRIEVAL_EXC(result, name);
105  }
106 }
107 
108 template <class DataType> ObjPtr<DataType> DataStore::GetFromMap(const std::string &name) {
109  return ObjectMap::GetObject<DataType>(name);
110 }
111 
112 template <class DataType>
113 ObjPtr<DataType> DataStore::CastAndWrap(const std::string &name, const std::string &actualName, ObjectWrapper &&wrapper,
114  observer_ptr<ObjectProducer> provider) {
115  ObjPtr<DataType> retObj;
117 
118  // Object found. Now check for type.
119  retObj = wrapper_cast<DataType>(wrapper);
120  if (retObj) {
121  if (actualName == "") {
122  if (ObjectMap::AddObject(name, std::move(wrapper)) == InsertionResult::DUPLICATE) {
123  // This can happen when an object with the same name but the wrong
124  // type is present in the data store, so that it has not been retrieved
125  // from stored objects in DataStore::GetObject due to a type mismatch but
126  // it prevents the object fetched from the provider to be inserted in the
127  // store
129  }
130  } else {
131  // name is actually an alias
132  ObjectMap::AddObject(actualName, std::move(wrapper)); // This fails if the aliased object is already present,
133  // so don't check the return value.
134  try {
135  SetAlias(actualName, name);
136  } catch (Insertion::Exception &exc) {
137  ObjectMap::RemoveObject(actualName);
138  retObj = nullptr;
140  }
141  }
142  } else {
144  }
145  // Add the object to the RemovedObjectsManager
146  if (provider && _remObjTracker) {
147  if (!_remObjTracker->TrackObject(name, provider)) {
148  retObj = nullptr;
150  }
151  }
152 
153  return retObj;
154 }
155 
156 template <class DataType> observer_ptr<DataType> EventDataStore::GetObject(const std::string &name) {
157 
158  // Retrieval of an object. The object will be fetched from the store, from the cache
159  // (if the cache exists) and from the data providers (if they exist) in this order.
160  // The retrieve result is the best result obtained in the above steps.
161 
162  // 1. Try to retrieve the requested object from existing ones
163  auto obj = GetFromMap<DataType>(name);
164  if (obj.GetRetrievalResult() == RetrievalResult::SUCCESS) {
165  return obj;
166  }
167 
168  ObjectWrapper w;
169  RetrievalResult result = obj.GetRetrievalResult();
170 
171  // 2. Try to retrieve the requested object from the cache
172  if (_eventCache) {
173  result = _eventCache->GetCachedValue(name, w);
174  }
175 
176  // 3. Try to retrieve the requested object from a registered provider
177  std::string actualName;
179  if (result != RetrievalResult::SUCCESS) {
180  // Insert the desired type into the wrapper
181  w = (DataType *)(nullptr);
182  // Retrieve from the provider
183  result = std::max(GetFromProvider(name, w, actualName, provider), result);
184  }
185 
186  // 4. Check the type if the object has been found.
187  if (result == RetrievalResult::SUCCESS) {
188  auto objPtr = CastAndWrap<DataType>(name, actualName, std::move(w), provider);
189  if (!objPtr) {
190  THROW_RETRIEVAL_EXC(objPtr.GetRetrievalResult(), name);
191  }
192  return objPtr;
193  } else {
194  if (result == RetrievalResult::NOTFOUND) {
195  // The object is not found in data providers, so let's see if it is produced by an algorithm to eventually
196  // return NOTAVAILABLE.
197  if (IsAlgoProducedObject(name)) {
198  throw Retrieval::NotAvailable("Object \"" + name + "\" is not available");
199  }
200 
201  // If there are other objects and aliases in the data store then throw a NotFound with a hint about a possible
202  // name mistake. Otherwise leave the duty of throwing a NotFound with a standard message to the
203  // THROW_RETRIEVAL_EXC macro below.
204  auto objsAndAliasesInStore = GetObjects();
205  {
206  auto aliasesInStore = GetAliases();
207  objsAndAliasesInStore.reserve(objsAndAliasesInStore.size() + aliasesInStore.size());
208  objsAndAliasesInStore.insert(objsAndAliasesInStore.end(), std::make_move_iterator(aliasesInStore.begin()),
209  std::make_move_iterator(aliasesInStore.end()));
210  }
211  if (objsAndAliasesInStore.size() != 0) {
212  auto hint = StringUtils::FindSimilar(name, objsAndAliasesInStore);
213  if (hint != "") {
214  throw Retrieval::NotFound("Object \"" + name + "\" is not found (most similar existing name/alias: \"" +
215  hint + "\")");
216  }
217  }
218  }
219  THROW_RETRIEVAL_EXC(result, name);
220  }
221 }
222 
223 } // namespace EA
224 
225 #endif /* DATASTORE_HPP_ */
observer_ptr< DataType > GetObject(const std::string &name)
Provides a data object.
Definition: DataStore.hpp:156
Class describing a pointer to an object retrieved from an ObjectMap.
Definition: ObjPtr.h:31
std::unique_ptr< RemovedObjectsTracker > _remObjTracker
Definition: DataStore.h:387
Known object but not available at the moment.
A smart pointer not owning the wrapped object.
Definition: ObserverPtr.h:28
#define THROW_RETRIEVAL_EXC(retRes, objName)
Definition: RetrievalExceptions.h:50
bool IsAlgoProducedObject(const std::string nameOrAlias)
Checks if a given object is produced by an algorithm.
Definition: DataStore.cpp:89
RetrievalResult
Definition: RetrievalResult.h:16
IncludeFileExc.h IncludeFileExc class declaration.
Definition: Algorithm.h:21
Exception for unknown object.
Definition: RetrievalExceptions.h:39
Exception for generic error in object insertion procedure.
Definition: InsertionExceptions.h:57
void SetAlias(const std::string &objName, const std::string &objAlias)
Set an alias for the given object.
Definition: DataStore.cpp:37
ObjPtr< DataType > GetFromMap(const std::string &name)
Retrieves an object from the internal ObjectMap.
Definition: DataStore.hpp:108
RetrievalResult GetFromProvider(const std::string &name, ObjectWrapper &wrapper, std::string &actualName, observer_ptr< ObjectProducer > &provider)
Retrieves an object from the registered providers.
Definition: DataStore.cpp:176
Generic wrapper class.
Definition: ObjectWrapper.h:28
void AddObject(const std::string &name, DataType &obj, const observer_ptr< ObjectProducer > &producer=nullptr)
Adds an object to the map, storing also the producer.
Definition: DataStore.hpp:15
Base class for insertion exceptions.
Definition: InsertionExceptions.h:21
std::vector< std::string > GetObjects() const
Returns the names of the objects in the store.
Definition: DataStore.h:163
ObjPtr< DataType > CastAndWrap(const std::string &name, const std::string &actualName, ObjectWrapper &&wrapper, observer_ptr< ObjectProducer > provider)
Casts the wrapper to the template type, registers the object in the store and wraps it inside the ret...
Definition: DataStore.hpp:113
InsertionResult AddObject(const std::string &name, DataType &obj)
Adds an object to the map.
Definition: ObjectMap.h:245
void * wrapper_cast(ObjectWrapper &wrapper, const std::type_info &typeInfo, bool isConst)
Cast function to extract wrapped pointer from wrapper in a type-safe way.
Definition: WrapperCast.cpp:12
InsertionResult
Definition: InsertionResult.h:16
bool RemoveObject(const std::string &name, bool removeAliased=false)
Removes an object or an alias from the map.
Definition: ObjectMap.cpp:79
std::vector< std::string > GetAliases(const std::string &name="") const
Returns the aliases of the objects in the store.
Definition: DataStore.h:223
Object successfully inserted or already present.
observer_ptr< DataType > GetObject(const std::string &name)
Provides a data object.
Definition: DataStore.hpp:67
Object found but class does not match with requested.
Exception for known object but not available at the moment.
Definition: RetrievalExceptions.h:27
std::enable_if_t<!(is_pointer< typename Container::value_type >::value), std::string > FindSimilar(const std::string &str, const Container &cont)
Find a similar string inside a container.
Definition: StringUtils.hpp:22
#define THROW_INSERTION_EXC(insRes, objName)
Definition: InsertionExceptions.h:62
RetrievalResult _result
Definition: ObjPtr.h:114