EntityQueryProcessorBase.h
Go to the documentation of this file.
1 #pragma once
2 
4 
7 
11 
12 #include <RobotAPI/interface/armem/query.h>
13 
14 #include <cstdint>
15 #include <iterator>
16 
17 
19 {
20  void checkReferenceTimestampNonNegative(const Time& timestamp);
21 }
23 {
24 
25  template <class _EntityT, class _ResultEntityT>
27  public BaseQueryProcessorBase<_EntityT, _ResultEntityT, armem::query::data::EntityQuery>
28  {
29  protected:
30 
32 
33  public:
34 
35  using EntityT = _EntityT;
37 
38  using ResultEntityT = _ResultEntityT;
40 
41 
42  public:
43 
44  using Base::process;
45  virtual void process(ResultEntityT& result,
46  const armem::query::data::EntityQuery& query,
47  const EntityT& entity) const override
48  {
49  if (auto q = dynamic_cast<const armem::query::data::entity::All*>(&query))
50  {
51  process(result, *q, entity);
52  }
53  else if (auto q = dynamic_cast<const armem::query::data::entity::Single*>(&query))
54  {
55  process(result, *q, entity);
56  }
57  else if (auto q = dynamic_cast<const armem::query::data::entity::TimeRange*>(&query))
58  {
59  process(result, *q, entity);
60  }
61  else if (auto q = dynamic_cast<const armem::query::data::entity::IndexRange*>(&query))
62  {
63  process(result, *q, entity);
64  }
65  else if (auto q = dynamic_cast<const armem::query::data::entity::TimeApprox*>(&query))
66  {
67  process(result, *q, entity);
68  }
69  else if (auto q = 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 
84  virtual void process(ResultEntityT& result,
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  {
93  this->addResultSnapshot(result, snapshot);
94  });
95  }
96 
97 
98  virtual void process(ResultEntityT& result,
99  const armem::query::data::entity::Single& query,
100  const EntityT& entity) const
101  {
102  if (query.timestamp.timeSinceEpoch.microSeconds < 0)
103  {
104  if (auto snapshot = entity.findLatestSnapshot())
105  {
106  this->addResultSnapshot(result, *snapshot);
107  }
108  }
109  else
110  {
111  const Time time = armarx::fromIce<Time>(query.timestamp);
112  if (auto snapshot = entity.findSnapshot(time))
113  {
114  this->addResultSnapshot(result, *snapshot);
115  }
116  else
117  {
118  // Leave empty.
119 #if 0
120  std::stringstream ss;
121  ss << "Failed to retrieve snapshot with timestamp "
123  << " from entity " << entity.id() << ".\n"
124  << "Entity has timestamps: ";
125  for (const Time& t : entity.getTimestamps())
126  {
127  ss << "\n- " << armem::toDateTimeMilliSeconds(t);
128  }
129  ARMARX_IMPORTANT << ss.str();
130 #endif
131  }
132  }
133  }
134 
135 
136  virtual void process(ResultEntityT& result,
137  const armem::query::data::entity::TimeRange& query,
138  const EntityT& entity) const
139  {
140  if (query.minTimestamp.timeSinceEpoch.microSeconds <= query.maxTimestamp.timeSinceEpoch.microSeconds
141  || query.minTimestamp.timeSinceEpoch.microSeconds < 0
142  || query.maxTimestamp.timeSinceEpoch.microSeconds < 0)
143  {
144  const Time min = armarx::fromIce<Time>(query.minTimestamp);
145  const Time max = armarx::fromIce<Time>(query.maxTimestamp);
146  process(result, min, max, entity, query);
147  }
148  }
149 
150 
151  virtual void process(ResultEntityT& result,
152  const armem::query::data::entity::IndexRange& query,
153  const EntityT& entity) const
154  {
156  query.first, query.last,
157  [this, &result](const EntitySnapshotT & snapshot)
158  {
159  this->addResultSnapshot(result, snapshot);
160  });
161  }
162 
163 
164  virtual void process(ResultEntityT& result,
165  const Time& min,
166  const Time& max,
167  const EntityT& entity,
168  const armem::query::data::EntityQuery& query) const
169  {
170  (void) query;
172  min, max,
173  [this, &result](const EntitySnapshotT & snapshot)
174  {
175  this->addResultSnapshot(result, snapshot);
176  });
177  }
178 
179 
180  virtual void process(ResultEntityT& result,
181  const armem::query::data::entity::BeforeOrAtTime& query,
182  const EntityT& entity) const
183  {
184  const Time referenceTimestamp = armarx::fromIce<Time>(query.timestamp);
186 
187  if (auto beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp))
188  {
189  this->addResultSnapshot(result, *beforeOrAt);
190  }
191  }
192 
193 
194  virtual void process(ResultEntityT& result,
195  const armem::query::data::entity::BeforeTime& query,
196  const EntityT& entity) const
197  {
198  const Time referenceTimestamp = armarx::fromIce<Time>(query.timestamp);
200 
201  std::vector<const EntitySnapshotT*> befores;
202  entity.forEachSnapshotBefore(referenceTimestamp, [&befores](const EntitySnapshotT & s)
203  {
204  befores.push_back(&s);
205  });
206 
207  size_t num = 0;
208  if (query.maxEntries < 0)
209  {
210  num = befores.size();
211  }
212  else
213  {
214  num = std::min(befores.size(), static_cast<size_t>(query.maxEntries));
215  }
216 
217  for (size_t r = 0; r < num; ++r)
218  {
219  size_t i = befores.size() - 1 - r;
220  this->addResultSnapshot(result, *befores[i]);
221  }
222  }
223 
224 
225  virtual void process(ResultEntityT& result,
226  const armem::query::data::entity::TimeApprox& query,
227  const EntityT& entity) const
228  {
229  const Time referenceTimestamp = armarx::fromIce<Time>(query.timestamp);
231 
232  // elements have to be in range [t_ref - eps, t_ref + eps] if eps is positive
233  const auto isInRange = [&](const Time & t) -> bool
234  {
235  return query.eps.microSeconds <= 0
236  or std::abs((t - referenceTimestamp).toMicroSeconds()) <= query.eps.microSeconds;
237  };
238 
239  // last element before or at timestamp
240  if (auto beforeOrAt = entity.findLatestSnapshotBeforeOrAt(referenceTimestamp))
241  {
242  const auto timestampOfMatchBefore = beforeOrAt->id().timestamp;
243  const auto isPerfectMatch = timestampOfMatchBefore == referenceTimestamp;
244  if (isInRange(timestampOfMatchBefore))
245  {
246  this->addResultSnapshot(result, *beforeOrAt);
247  }
248 
249  // earsly stop, not necessary to also get the next since the match is perfect
250  if (isPerfectMatch)
251  {
252  return;
253  }
254 
255  // first element after or at timestamp (or at because of fewer checks, we can assure that there is not element at)
256  const auto after = entity.findFirstSnapshotAfterOrAt(referenceTimestamp);
257  if (after)
258  {
259  const auto timestampOfMatchAfter = after->id().timestamp;
260  if (isInRange(timestampOfMatchAfter))
261  {
262  this->addResultSnapshot(result, *after);
263  }
264  }
265  }
266  }
267 
268 
269  protected:
270 
271  virtual void addResultSnapshot(ResultEntityT& result, const EntitySnapshotT& snapshot) const = 0;
272 
273  };
274 }
armarx::armem::server::query_proc::base
Definition: BaseQueryProcessorBase.cpp:6
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:38
BaseQueryProcessorBase.h
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
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:180
armarx::armem::server::query_proc::base::detail
Definition: EntityQueryProcessorBase.h:18
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:21
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:39
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:267
armarx::armem::server::query_proc::base::EntityQueryProcessorBase
Definition: EntityQueryProcessorBase.h:26
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:45
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:253
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:36
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:136
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:164
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:294
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:194
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:42
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:33
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:225
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:98
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:151