EntityQueryProcessorBase.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdint>
4 #include <iterator>
5 
8 
9 #include <RobotAPI/interface/armem/query.h>
13 
14 #include "BaseQueryProcessorBase.h"
15 
17 {
18  void checkReferenceTimestampNonNegative(const Time& timestamp);
19 }
20 
22 {
23 
24  template <class _EntityT, class _ResultEntityT>
26  public BaseQueryProcessorBase<_EntityT, _ResultEntityT, armem::query::data::EntityQuery>
27  {
28  protected:
29  using Base =
31 
32  public:
33  using EntityT = _EntityT;
35 
36  using ResultEntityT = _ResultEntityT;
38 
39 
40  public:
41  using Base::process;
42 
43  virtual void
45  const armem::query::data::EntityQuery& query,
46  const EntityT& entity) const override
47  {
48  if (auto q = dynamic_cast<const armem::query::data::entity::All*>(&query))
49  {
50  process(result, *q, entity);
51  }
52  else if (auto q = dynamic_cast<const armem::query::data::entity::Single*>(&query))
53  {
54  process(result, *q, entity);
55  }
56  else if (auto q = dynamic_cast<const armem::query::data::entity::TimeRange*>(&query))
57  {
58  process(result, *q, entity);
59  }
60  else if (auto q = dynamic_cast<const armem::query::data::entity::IndexRange*>(&query))
61  {
62  process(result, *q, entity);
63  }
64  else if (auto q = dynamic_cast<const armem::query::data::entity::TimeApprox*>(&query))
65  {
66  process(result, *q, entity);
67  }
68  else if (auto q =
69  dynamic_cast<const armem::query::data::entity::BeforeOrAtTime*>(&query))
70  {
71  process(result, *q, entity);
72  }
73  else if (auto q = dynamic_cast<const armem::query::data::entity::BeforeTime*>(&query))
74  {
75  process(result, *q, entity);
76  }
77  else
78  {
79  throw armem::error::UnknownQueryType("entity snapshot", query);
80  }
81  }
82 
83  virtual void
85  const armem::query::data::entity::All& query,
86  const EntityT& entity) const
87  {
88  (void)query;
89  // Copy this entitiy and its contents.
90 
91  entity.forEachSnapshot([this, &result](const EntitySnapshotT& snapshot)
92  { this->addResultSnapshot(result, snapshot); });
93  }
94 
95  virtual void
97  const armem::query::data::entity::Single& query,
98  const EntityT& entity) const
99  {
100  if (query.timestamp.timeSinceEpoch.microSeconds < 0)
101  {
102  if (auto snapshot = entity.findLatestSnapshot())
103  {
104  this->addResultSnapshot(result, *snapshot);
105  }
106  }
107  else
108  {
109  const Time time = armarx::fromIce<Time>(query.timestamp);
110  if (auto snapshot = entity.findSnapshot(time))
111  {
112  this->addResultSnapshot(result, *snapshot);
113  }
114  else
115  {
116  // Leave empty.
117 #if 0
118  std::stringstream ss;
119  ss << "Failed to retrieve snapshot with timestamp "
121  << " from entity " << entity.id() << ".\n"
122  << "Entity has timestamps: ";
123  for (const Time& t : entity.getTimestamps())
124  {
125  ss << "\n- " << armem::toDateTimeMilliSeconds(t);
126  }
127  ARMARX_IMPORTANT << ss.str();
128 #endif
129  }
130  }
131  }
132 
133  virtual void
135  const armem::query::data::entity::TimeRange& query,
136  const EntityT& entity) const
137  {
138  if (query.minTimestamp.timeSinceEpoch.microSeconds <=
139  query.maxTimestamp.timeSinceEpoch.microSeconds ||
140  query.minTimestamp.timeSinceEpoch.microSeconds < 0 ||
141  query.maxTimestamp.timeSinceEpoch.microSeconds < 0)
142  {
143  const Time min = armarx::fromIce<Time>(query.minTimestamp);
144  const Time max = armarx::fromIce<Time>(query.maxTimestamp);
145  process(result, min, max, entity, query);
146  }
147  }
148 
149  virtual void
151  const armem::query::data::entity::IndexRange& query,
152  const EntityT& entity) const
153  {
154  entity.forEachSnapshotInIndexRange(query.first,
155  query.last,
156  [this, &result](const EntitySnapshotT& snapshot)
157  { this->addResultSnapshot(result, snapshot); });
158  }
159 
160  virtual void
162  const Time& min,
163  const Time& max,
164  const EntityT& entity,
165  const armem::query::data::EntityQuery& query) const
166  {
167  (void)query;
169  max,
170  [this, &result](const EntitySnapshotT& snapshot)
171  { this->addResultSnapshot(result, snapshot); });
172  }
173 
174  virtual void
176  const armem::query::data::entity::BeforeOrAtTime& query,
177  const EntityT& entity) const
178  {
179  const Time referenceTimestamp = armarx::fromIce<Time>(query.timestamp);
181 
182  if (auto beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp))
183  {
184  this->addResultSnapshot(result, *beforeOrAt);
185  }
186  }
187 
188  virtual void
190  const armem::query::data::entity::BeforeTime& query,
191  const EntityT& entity) const
192  {
193  const Time referenceTimestamp = armarx::fromIce<Time>(query.timestamp);
195 
196  std::vector<const EntitySnapshotT*> befores;
197  entity.forEachSnapshotBefore(referenceTimestamp,
198  [&befores](const EntitySnapshotT& s)
199  { befores.push_back(&s); });
200 
201  size_t num = 0;
202  if (query.maxEntries < 0)
203  {
204  num = befores.size();
205  }
206  else
207  {
208  num = std::min(befores.size(), static_cast<size_t>(query.maxEntries));
209  }
210 
211  for (size_t r = 0; r < num; ++r)
212  {
213  size_t i = befores.size() - 1 - r;
214  this->addResultSnapshot(result, *befores[i]);
215  }
216  }
217 
218  virtual void
220  const armem::query::data::entity::TimeApprox& query,
221  const EntityT& entity) const
222  {
223  const Time referenceTimestamp = armarx::fromIce<Time>(query.timestamp);
225 
226  // elements have to be in range [t_ref - eps, t_ref + eps] if eps is positive
227  const auto isInRange = [&](const Time& t) -> bool
228  {
229  return query.eps.microSeconds <= 0 or
230  std::abs((t - referenceTimestamp).toMicroSeconds()) <=
231  query.eps.microSeconds;
232  };
233 
234  // last element before or at timestamp
235  if (auto beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp))
236  {
237  const auto timestampOfMatchBefore = beforeOrAt->id().timestamp;
238  const auto isPerfectMatch = timestampOfMatchBefore == referenceTimestamp;
239  if (isInRange(timestampOfMatchBefore))
240  {
241  this->addResultSnapshot(result, *beforeOrAt);
242  }
243 
244  // earsly stop, not necessary to also get the next since the match is perfect
245  if (isPerfectMatch)
246  {
247  return;
248  }
249 
250  // first element after or at timestamp (or at because of fewer checks, we can assure that there is not element at)
251  const auto after = entity.findFirstSnapshotAfterOrAt(referenceTimestamp);
252  if (after)
253  {
254  const auto timestampOfMatchAfter = after->id().timestamp;
255  if (isInRange(timestampOfMatchAfter))
256  {
257  this->addResultSnapshot(result, *after);
258  }
259  }
260  }
261  }
262 
263 
264  protected:
265  virtual void addResultSnapshot(ResultEntityT& result,
266  const EntitySnapshotT& snapshot) const = 0;
267  };
268 } // namespace armarx::armem::server::query_proc::base
armarx::armem::server::query_proc::base
Definition: BaseQueryProcessorBase.cpp:5
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::query_proc::base::EntityQueryProcessorBase::ResultEntityT
_ResultEntityT ResultEntityT
Definition: EntityQueryProcessorBase.h:36
BaseQueryProcessorBase.h
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::BeforeOrAtTime &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:175
armarx::armem::server::query_proc::base::detail
Definition: EntityQueryProcessorBase.h:16
armarx::armem::server::ltm::Entity::findFirstSnapshotAfterOrAt
std::shared_ptr< EntitySnapshot > findFirstSnapshotAfterOrAt(const Time &time) const override
Definition: Entity.cpp:319
armarx::armem::server::query_proc::base::BaseQueryProcessorBase
Base class for memory query processors.
Definition: BaseQueryProcessorBase.h:20
armarx::armem::server::ltm::Entity
A memory storing data in mongodb (needs 'armarx memory start' to start the mongod instance)
Definition: Entity.h:14
armarx::armem::server::query_proc::base::EntityQueryProcessorBase< armem::server::ltm::Entity, armem::wm::Entity >::ResultSnapshotT
typename ResultEntityT::EntitySnapshotT ResultSnapshotT
Definition: EntityQueryProcessorBase.h:37
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:297
armarx::armem::server::query_proc::base::EntityQueryProcessorBase
Definition: EntityQueryProcessorBase.h:25
ice_conversions.h
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::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::EntityQuery &query, const EntityT &entity) const override
Process the query and populate result.
Definition: EntityQueryProcessorBase.h:44
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
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::EntityBase< EntitySnapshot, Entity >::EntitySnapshotT
EntitySnapshot EntitySnapshotT
Definition: EntityBase.h:56
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
armarx::armem::toDateTimeMilliSeconds
std::string toDateTimeMilliSeconds(const Time &time, int decimals=6)
Returns timeas e.g.
Definition: Time.cpp:35
error.h
ice_conversions.h
armarx::armem::server::query_proc::base::EntityQueryProcessorBase< armem::server::ltm::Entity, armem::wm::Entity >::EntitySnapshotT
typename EntityT::EntitySnapshotT EntitySnapshotT
Definition: EntityQueryProcessorBase.h:34
q
#define q
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::TimeRange &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:134
armarx::core::time::DateTime
Represents a point in time.
Definition: DateTime.h:24
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::All &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:84
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::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const Time &min, const Time &max, const EntityT &entity, const armem::query::data::EntityQuery &query) const
Definition: EntityQueryProcessorBase.h:161
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:327
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::BeforeTime &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:189
Time.h
armarx::armem::server::ltm::Entity::findLatestSnapshot
std::shared_ptr< EntitySnapshot > findLatestSnapshot() const override
Definition: Entity.cpp:207
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::addResultSnapshot
virtual void addResultSnapshot(ResultEntityT &result, const EntitySnapshotT &snapshot) const =0
armarx::armem::server::ltm::Entity::findLatestSnapshotBeforeOrAt
std::shared_ptr< EntitySnapshot > findLatestSnapshotBeforeOrAt(const Time &time) const override
Definition: Entity.cpp:263
ice_conversions_templates.h
armarx::armem::wm::Entity
Client-side working memory entity.
Definition: memory_definitions.h:93
min
T min(T t1, T t2)
Definition: gdiam.h:44
armarx::armem::server::query_proc::base::BaseQueryProcessorBase< _EntityT, _ResultEntityT, armem::query::data::EntityQuery >::process
_ResultEntityT process(const armem::query::data::EntityQuery &query, const _EntityT &data) const
Definition: BaseQueryProcessorBase.h:31
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::TimeApprox &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:219
armarx::armem::server::ltm::EntitySnapshot
Definition: EntitySnapshot.h:14
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::Single &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:96
armarx::armem::error::UnknownQueryType
Indicates that an entity's history was queried, but is empty.
Definition: ArMemError.h:173
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx::armem::server::query_proc::base::detail::checkReferenceTimestampNonNegative
void checkReferenceTimestampNonNegative(const Time &timestamp)
Definition: EntityQueryProcessorBase.cpp:8
armarx::armem::server::query_proc::base::EntityQueryProcessorBase::process
virtual void process(ResultEntityT &result, const armem::query::data::entity::IndexRange &query, const EntityT &entity) const
Definition: EntityQueryProcessorBase.h:150