Entity.cpp
Go to the documentation of this file.
1 // Header
2 #include "Entity.h"
3 
4 // SImox
5 #include <SimoxUtility/algorithm/string.h>
6 
7 // ArmarX
10 
13 
15 
17 {
18  namespace util
19  {
20 
21 
22  } // namespace util
23 
26 
27  const std::string& exportName,
28  const armem::MemoryID& id /* UNESCAPED */,
29  const std::shared_ptr<Processors>& filters) :
30  EntityBase(exportName, id, filters),
31  DiskMemoryItemMixin(p, exportName, id),
32  MongoDBStorageMixin(s, exportName, id)
33  {
34  //start();
35  }
36 
37  bool
38  Entity::forEachSnapshot(std::function<void(EntitySnapshot&)> func) const
39  {
40  std::lock_guard l(ltm_mutex);
41 
42  if (fullPathExists())
43  {
44 
45  for (const auto& d : getAllDirectories()) // days
46  {
47  if (!util::fs::detail::isDateString(d.filename()))
48  {
49  ARMARX_WARNING << "Found a non-date folder inside an entity '" << id().str()
50  << "' with name '" << d.filename() << "'. "
51  << "Ignoring this folder, however this is a bad situation.";
52  continue;
53  }
54 
55 
56  for (const auto& s : util::fs::getAllDirectories(d)) // seconds
57  {
58  if (!util::fs::detail::isNumberString(s.filename()))
59  {
60  ARMARX_WARNING << "Found a non-timestamp folder inside an entity '"
61  << id().str() << "' hours folder with name '" << s.filename()
62  << "'. "
63  << "Ignoring this folder, however this is a bad situation.";
64  continue;
65  }
66 
67  for (const auto& us : util::fs::getAllDirectories(s)) // microseconds
68  {
69  if (!util::fs::detail::isNumberString(us.filename()))
70  {
72  << "Found a non-timestamp folder inside an entity '" << id().str()
73  << "' seconds folder with name '" << us.filename() << "'. "
74  << "Ignoring this folder, however this is a bad situation.";
75  continue;
76  }
77 
78 
81  getSettings(),
82  getExportName(),
83  id().withTimestamp(timeFromStringMicroSeconds(us.filename())),
84  processors);
85  func(c);
86  }
87  }
88  }
89  }
90 
91  return true;
92  }
93 
94  bool
96  long last,
97  std::function<void(EntitySnapshot&)> func) const
98  {
99  std::lock_guard l(ltm_mutex);
100  //ARMARX_WARNING << "PLEASE NOTE THAT QUERYING THE LTM INDEX WISE MAY BE BUGGY BECAUSE THE FILESYSTEM ITERATOR IS UNSORTED!";
101 
102  if (first < 0 or last < 0)
103  {
104  // We need to know what the size of the memory is... May be slow
105  unsigned long size = 0;
106  auto f = [&](EntitySnapshot& e) { size++; };
107  forEachSnapshot(std::move(f));
108 
111  }
112 
113  long checked = 0;
114  auto f = [&](EntitySnapshot& e)
115  {
116  if (checked >= first && checked <= last)
117  {
118  func(e);
119  }
120  checked++;
121  };
122 
123  return forEachSnapshot(std::move(f));
124  }
125 
126  bool
128  const Time& max,
129  std::function<void(EntitySnapshot&)> func) const
130  {
131  std::lock_guard l(ltm_mutex);
132  auto f = [&](EntitySnapshot& e)
133  {
134  auto ts = e.id().timestamp;
135  if (ts >= min && ts <= max)
136  {
137  func(e);
138  }
139  };
140 
141  return forEachSnapshot(std::move(f));
142  }
143 
144  bool
146  std::function<void(EntitySnapshot&)> func) const
147  {
148  std::lock_guard l(ltm_mutex);
149  auto f = [&](EntitySnapshot& e)
150  {
151  auto ts = e.id().timestamp;
152  if (ts <= time)
153  {
154  func(e);
155  }
156  };
157 
158  return forEachSnapshot(std::move(f));
159  }
160 
161  bool
162  Entity::forEachSnapshotBefore(const Time& time, std::function<void(EntitySnapshot&)> func) const
163  {
164  std::lock_guard l(ltm_mutex);
165  auto f = [&](EntitySnapshot& e)
166  {
167  auto ts = e.id().timestamp;
168  if (ts < time)
169  {
170  func(e);
171  }
172  };
173 
174  return forEachSnapshot(std::move(f));
175  }
176 
177  bool
178  Entity::hasSnapshot(const Time& n) const
179  {
180  std::lock_guard l(ltm_mutex);
181 
182  if (fullPathExists())
183  {
185  getSettings(),
186  getExportName(),
187  id().withTimestamp(n),
188  processors);
189  return c.fullPathExists();
190  }
191  return false;
192  }
193 
194  std::shared_ptr<EntitySnapshot>
195  Entity::findSnapshot(const Time& n) const
196  {
197  std::lock_guard l(ltm_mutex);
198  if (!hasSnapshot(n))
199  {
200  return nullptr;
201  }
202  return std::make_shared<EntitySnapshot>(
203  getMemoryBasePath(), getSettings(), getExportName(), id().withTimestamp(n), processors);
204  }
205 
206  std::shared_ptr<EntitySnapshot>
208  {
209  std::lock_guard l(ltm_mutex);
210  Time bestMatch = Time::Invalid();
211  auto f = [&](EntitySnapshot& e)
212  {
213  auto ts = e.id().timestamp;
214  if (ts > bestMatch)
215  {
216  bestMatch = ts;
217  }
218  };
219 
220  forEachSnapshot(std::move(f));
221 
222  if (bestMatch == Time::Invalid())
223  {
224  return nullptr;
225  }
226 
227  return std::make_shared<EntitySnapshot>(getMemoryBasePath(),
228  getSettings(),
229  getExportName(),
230  id().withTimestamp(bestMatch),
231  processors);
232  }
233 
234  std::shared_ptr<EntitySnapshot>
236  {
237  std::lock_guard l(ltm_mutex);
238  Time bestMatch = Time::Invalid();
239  auto f = [&](EntitySnapshot& e)
240  {
241  auto ts = e.id().timestamp;
242  if (ts < time && ts > bestMatch)
243  {
244  bestMatch = ts;
245  }
246  };
247 
248  forEachSnapshot(std::move(f));
249 
250  if (bestMatch == Time::Invalid())
251  {
252  return nullptr;
253  }
254 
255  return std::make_shared<EntitySnapshot>(getMemoryBasePath(),
256  getSettings(),
257  getExportName(),
258  id().withTimestamp(bestMatch),
259  processors);
260  }
261 
262  std::shared_ptr<EntitySnapshot>
264  {
265  std::lock_guard l(ltm_mutex);
266  Time bestMatch = Time::Invalid();
267  auto f = [&](EntitySnapshot& e)
268  {
269  auto ts = e.id().timestamp;
270  if (ts <= time && ts > bestMatch)
271  {
272  bestMatch = ts;
273  }
274  };
275 
276  forEachSnapshot(std::move(f));
277 
278  if (bestMatch == Time::Invalid())
279  {
280  return nullptr;
281  }
282 
283  return std::make_shared<EntitySnapshot>(getMemoryBasePath(),
284  getSettings(),
285  getExportName(),
286  id().withTimestamp(bestMatch),
287  processors);
288  }
289 
290  std::shared_ptr<EntitySnapshot>
292  {
293  std::lock_guard l(ltm_mutex);
295  auto f = [&](EntitySnapshot& e)
296  {
297  auto ts = e.id().timestamp;
298  if (ts > time && ts < bestMatch)
299  {
300  bestMatch = ts;
301  }
302  };
303 
304  forEachSnapshot(std::move(f));
305 
307  {
308  return nullptr;
309  }
310 
311  return std::make_shared<EntitySnapshot>(getMemoryBasePath(),
312  getSettings(),
313  getExportName(),
314  id().withTimestamp(bestMatch),
315  processors);
316  }
317 
318  std::shared_ptr<EntitySnapshot>
320  {
321  std::lock_guard l(ltm_mutex);
323  auto f = [&](EntitySnapshot& e)
324  {
325  auto ts = e.id().timestamp;
326  if (ts >= time && ts < bestMatch)
327  {
328  bestMatch = ts;
329  }
330  };
331 
332  forEachSnapshot(std::move(f));
333 
335  {
336  return nullptr;
337  }
338 
339  return std::make_shared<EntitySnapshot>(getMemoryBasePath(),
340  getSettings(),
341  getExportName(),
342  id().withTimestamp(bestMatch),
343  processors);
344  }
345 
346  void
348  {
349  std::lock_guard l(ltm_mutex);
350  e.id() = id().getEntityID().cleanID();
351 
353  [&e](auto& x)
354  {
355  if (!e.hasSnapshot(
356  x.id()
357  .timestamp)) // we only load the references if the snapshot is not existant
358  {
359  armem::wm::EntitySnapshot s;
360  x.loadAllReferences(s);
361  e.addSnapshot(s);
362  }
363  });
364  }
365 
366  void
368  {
369  std::lock_guard l(ltm_mutex);
370  e.id() = id().getEntityID().cleanID();
371  int count = 0;
372 
373  //this is a little bit ugly, TODO: find an easier way to count the snapshots
375  [&e, &count](auto& x)
376  {
377  count++;
378  }
379  );
380 
381  int current = 0;
382 
384  [&e, &n, &current, &count](auto& x)
385  {
386  if (!e.hasSnapshot(
387  x.id()
388  .timestamp)) // we only load the references if the snapshot is not existant
389  {
390  if (current >= (count - n)){
391  ARMARX_INFO << e.id().coreSegmentName << ": count: " << count << ", n: " << n << ", current: " << current;
392  ARMARX_DEBUG << "Loading snapshot with timestamp " << x.id().timestamp << " into WM";
393  armem::wm::EntitySnapshot s;
394  x.loadAllReferences(s);
395  e.addSnapshot(s);
396  } else {
397  ARMARX_DEBUG << "Skipping snapshot with timestamp " << x.id().timestamp;
398  }
399  current++;
400  }
401  });
402  }
403 
404  void
405  Entity::_resolve(armem::wm::Entity& p)
406  {
407  std::lock_guard l(ltm_mutex);
408 
409  if (/*(connected() && collectionExists()) ||*/ fullPathExists())
410  {
411 
412  p.forEachSnapshot(
413  [&](auto& e)
414  {
415  EntitySnapshot c(getMemoryBasePath(),
416  getSettings(),
417  getExportName(),
418  id().withTimestamp(e.id().timestamp),
419  processors);
420  c.resolve(e);
421  });
422  }
423  }
424 
425  void
426  Entity::_store(const armem::wm::Entity& c)
427  {
428  std::lock_guard l(ltm_mutex);
429  if (id().entityName.empty())
430  {
432  << "During storage of segment '" << c.id().str()
433  << "' I noticed that the corresponding LTM has no id set. "
434  << "I set the id of the LTM to the same name, however this should not happen!";
435  id().entityName = c.id().entityName;
436  }
437 
438  /*if (!connected())
439  {
440  ARMARX_WARNING << "LTM ENTITY NOT CONNECTED ALTHOUGH ENABLED " << id().str();
441  return;
442  }*/
443 
444  //writeForeignKeyToPreviousDocument();
445 
446  c.forEachSnapshot(
447  [&](const auto& snap)
448  {
449  EntitySnapshot c(getMemoryBasePath(),
450  getSettings(),
451  getExportName(),
452  id().withTimestamp(snap.id().timestamp),
453  processors);
454 
455  // check if snapshot already exists
456 
457  if (hasSnapshot(snap.id().timestamp))
458  {
459  ARMARX_INFO << "Ignoring to put an EntitiySnapshot into the LTM because "
460  "the timestamp already existed (we assume snapshots are "
461  "const and do not change outside the ltm).";
462  return;
463  }
464 
465  for (auto& f : processors->snapFilters)
466  {
467 
468  bool accepted = f->accept(snap);
469  if (!accepted)
470  {
471  //ARMARX_INFO << "Ignoring to put an EntitiySnapshot into the LTM because it got filtered.";
472  return;
473  } else {
474  //ARMARX_INFO << "Storing EntitySnapshot";
475  }
476  }
477 
478  c.store(snap);
479  statistics.recordedSnapshots++;
480  });
481  }
482 } // namespace armarx::armem::server::ltm
armarx::armem::server::ltm::Entity::forEachSnapshotBefore
bool forEachSnapshotBefore(const Time &time, std::function< void(EntitySnapshot &)> func) const override
Definition: Entity.cpp:162
armarx::armem::server::ltm::detail::MemoryItem::processors
std::shared_ptr< Processors > processors
Definition: MemoryItem.h:54
armarx::armem::server::ltm::Entity::findLatestSnapshotBefore
std::shared_ptr< EntitySnapshot > findLatestSnapshotBefore(const Time &time) const override
Definition: Entity.cpp:235
Entity.h
armarx::armem::server::ltm::detail::mixin::DiskMemoryItemMixin::getMemoryBasePath
Path getMemoryBasePath() const
Definition: DiskStorageMixin.cpp:71
armarx::armem::server::ltm::Entity::_loadLatestNReferences
void _loadLatestNReferences(int n, armem::wm::Entity &e) override
Definition: Entity.cpp:367
armarx::armem::server::ltm::Entity::findFirstSnapshotAfterOrAt
std::shared_ptr< EntitySnapshot > findFirstSnapshotAfterOrAt(const Time &time) const override
Definition: Entity.cpp:319
armarx::armem::MemoryID::str
std::string str(bool escapeDelimiters=true) const
Get a string representation of this memory ID.
Definition: MemoryID.cpp:102
armarx::armem::timeFromStringMicroSeconds
Time timeFromStringMicroSeconds(const std::string &microSeconds)
Get a Time from the microseconds as text.
Definition: Time.cpp:50
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:267
armarx::armem::server::ltm::Entity::findFirstSnapshotAfter
std::shared_ptr< EntitySnapshot > findFirstSnapshotAfter(const Time &time) const override
Definition: Entity.cpp:291
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::armem::server::ltm::Entity::forEachSnapshot
bool forEachSnapshot(std::function< void(EntitySnapshot &)> func) const override
iterate over all entity snapshots of this ltm
Definition: Entity.cpp:38
armarx::armem::server::ltm::Entity::hasSnapshot
bool hasSnapshot(const Time &) const override
check if snapshot segment exists
Definition: Entity.cpp:178
armarx::armem::server::ltm::Entity::forEachSnapshotInTimeRange
bool forEachSnapshotInTimeRange(const Time &min, const Time &max, std::function< void(EntitySnapshot &)> func) const override
Definition: Entity.cpp:127
memory_definitions.h
armarx::armem::server::ltm::detail::mixin::DiskMemoryItemMixin::getAllDirectories
std::vector< Path > getAllDirectories() const
Definition: DiskStorageMixin.cpp:160
armarx::armem::server::ltm::Entity::findSnapshot
std::shared_ptr< EntitySnapshot > findSnapshot(const Time &) const override
find entity snapshot segment
Definition: Entity.cpp:195
armarx::armem::base::detail::negativeIndexSemantics
size_t negativeIndexSemantics(long index, size_t size)
Definition: negative_index_semantics.cpp:6
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
armarx::armem::server::ltm::Entity::forEachSnapshotBeforeOrAt
bool forEachSnapshotBeforeOrAt(const Time &time, std::function< void(EntitySnapshot &)> func) const override
Definition: Entity.cpp:145
armarx::armem::server::ltm::util::fs::getAllDirectories
std::vector< std::filesystem::path > getAllDirectories(const std::filesystem::path &p)
Definition: filesystem.cpp:202
armarx::armem::server::ltm::detail::mixin::MongoDBStorageMixin::getSettings
MongoDBSettings getSettings() const
Definition: MongoDBStorageMixin.cpp:436
max
T max(T t1, T t2)
Definition: gdiam.h:48
armarx::armem::server::ltm::detail::MemoryItem::getExportName
virtual std::string getExportName() const
Definition: MemoryItem.h:26
armarx::armem::server::ltm::detail::EntityBase< EntitySnapshot >::ltm_mutex
std::recursive_mutex ltm_mutex
Definition: EntityBase.h:114
armarx::armem::base::detail::MemoryItem::id
MemoryID & id()
Definition: MemoryItem.h:27
armarx::armem::server::ltm::util::fs::detail::isNumberString
bool isNumberString(const std::string &s)
Definition: filesystem.cpp:68
negative_index_semantics.h
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::armem::server::ltm::Entity::Entity
Entity(const detail::mixin::Path &, const detail::mixin::MongoDBSettings &, const std::string &, const MemoryID &id, const std::shared_ptr< Processors > &)
Definition: Entity.cpp:24
armarx::armem::server::ltm::Entity::_loadAllReferences
void _loadAllReferences(armem::wm::Entity &) override
Definition: Entity.cpp:347
armarx::armem::server::ltm
Definition: forward_declarations.h:20
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::armem::MemoryID::getEntityID
MemoryID getEntityID() const
Definition: MemoryID.cpp:305
armarx::armem::server::wm::EntitySnapshot
armem::wm::EntitySnapshot EntitySnapshot
Definition: forward_declarations.h:65
armarx::armem::server::ltm::detail::MemoryItem::id
MemoryID id() const
Definition: MemoryItem.cpp:37
armarx::armem::server::ltm::Entity::forEachSnapshotInIndexRange
bool forEachSnapshotInIndexRange(long first, long last, std::function< void(EntitySnapshot &)> func) const override
Definition: Entity.cpp:95
armarx::armem::MemoryID::cleanID
MemoryID cleanID() const
Definition: MemoryID.cpp:132
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::armem::base::EntityBase::hasSnapshot
bool hasSnapshot(const Time &time) const
Indicate whether a snapshot at the given time exists.
Definition: EntityBase.h:114
FrequencyFilter.h
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:294
armarx::armem::server::ltm::util::fs::detail::isDateString
bool isDateString(const std::string &s)
Definition: filesystem.cpp:81
armarx::armem::server::ltm::detail::mixin::DiskMemoryItemMixin::fullPathExists
bool fullPathExists() const
Definition: DiskStorageMixin.cpp:110
armarx::armem::server::ltm::Entity::findLatestSnapshot
std::shared_ptr< EntitySnapshot > findLatestSnapshot() const override
Definition: Entity.cpp:207
armarx::armem::server::ltm::Entity::findLatestSnapshotBeforeOrAt
std::shared_ptr< EntitySnapshot > findLatestSnapshotBeforeOrAt(const Time &time) const override
Definition: Entity.cpp:263
armarx::armem::server::ltm::detail::mixin::MongoDBSettings
Definition: MongoDBStorageMixin.h:15
armarx::armem::server::ltm::detail::mixin::Path
std::filesystem::path Path
Definition: DiskStorageMixin.h:17
armarx::armem::base::EntityBase::forEachSnapshot
bool forEachSnapshot(SnapshotFunctionT &&func)
Definition: EntityBase.h:390
armarx::armem::wm::Entity
Client-side working memory entity.
Definition: memory_definitions.h:93
Logging.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::core::time::Duration::MicroSeconds
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
Definition: Duration.cpp:27
armarx::armem::server::ltm::EntitySnapshot
Definition: EntitySnapshot.h:14
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx::core::time::DateTime::Invalid
static DateTime Invalid()
Definition: DateTime.cpp:60