swift
timestampobjectlist.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_TIMESTAMPOBJECTLIST_H
7 #define SWIFT_MISC_TIMESTAMPOBJECTLIST_H
8 
9 #include <QtGlobal>
10 
11 #include "config/buildconfig.h"
12 #include "misc/predicates.h"
13 #include "misc/swiftmiscexport.h"
14 #include "misc/timestampbased.h"
15 #include "misc/verify.h"
16 
17 class QDateTime;
18 
19 namespace swift::misc
20 {
23  {
24  qint64 min;
25  qint64 max;
26  double mean;
27 
29  bool isValid() const { return min >= 0 && max >= 0; }
30 
32  void reset()
33  {
34  min = -1;
35  max = -1;
36  mean = -1;
37  }
38 
40  QString asString() const
41  {
42  return QStringLiteral("Min: %1ms Max: %2ms Mean: %3ms").arg(min).arg(max).arg(mean, 0, 'f', 2);
43  }
44  };
45 
48  template <class OBJ, class CONTAINER>
50  {
51  static_assert(std::is_base_of_v<ITimestampBased, OBJ>, "OBJ needs to implement ITimestampBased");
52 
53  public:
56  {
57  NoTimestampSortHint,
58  TimestampLatestFirst,
59  TimestampLatestLast
60  };
61 
63  CONTAINER findBefore(const QDateTime &dateTime) const { return this->findBefore(dateTime.toMSecsSinceEpoch()); }
64 
66  CONTAINER findBefore(qint64 msSinceEpoch) const
67  {
68  return this->container().findBy([&](const OBJ &obj) { return obj.isOlderThan(msSinceEpoch); });
69  }
70 
72  OBJ findObjectBeforeOrDefault(qint64 msSinceEpoch) const
73  {
74  const CONTAINER before = this->findBefore(msSinceEpoch);
75  if (before.isEmpty()) { return OBJ(); }
76  return before.latestObject();
77  }
78 
80  CONTAINER findBeforeAndRemove(qint64 msSinceEpoch)
81  {
82  CONTAINER result(findBefore(msSinceEpoch));
83  this->removeBefore(msSinceEpoch);
84  return result;
85  }
86 
88  CONTAINER findBeforeNowMinusOffset(qint64 msOffset) const
89  {
90  return this->findBefore(QDateTime::currentMSecsSinceEpoch() - msOffset);
91  }
92 
94  CONTAINER findAfter(const QDateTime &dateTime) const { return this->findAfter(dateTime.toMSecsSinceEpoch()); }
95 
97  CONTAINER findAfter(qint64 msSinceEpoch) const
98  {
99  return this->container().findBy([&](const OBJ &obj) { return obj.isNewerThan(msSinceEpoch); });
100  }
101 
103  CONTAINER findAfterNowMinusOffset(qint64 msOffset) const
104  {
105  return this->findAfter(QDateTime::currentMSecsSinceEpoch() - msOffset);
106  }
107 
109  OBJ findObjectAfterOrDefault(qint64 msSinceEpoch) const
110  {
111  const CONTAINER after = this->findAfter(msSinceEpoch);
112  if (after.isEmpty()) { return OBJ(); }
113  return after.oldestObject();
114  }
115 
117  CONTAINER findInvalidTimestamps() const
118  {
119  return this->container().findBy([&](const OBJ &obj) { return !obj.hasValidTimestamp(); });
120  }
121 
123  OBJ findClosestTimeDistance(qint64 msSinceEpoch) const
124  {
125  if (this->container().isEmpty()) { return OBJ(); }
126  const auto closest = std::min_element(this->container().cbegin(), this->container().cend(),
127  [=](const ITimestampBased &a, const ITimestampBased &b) {
128  return qAbs(a.getTimeDifferenceMs(msSinceEpoch)) <
129  qAbs(b.getTimeDifferenceMs(msSinceEpoch));
130  });
131  return *closest;
132  }
133 
135  bool hasInvalidTimestamps() const { return this->container().contains(&OBJ::hasValidTimestamp, false); }
136 
139  {
140  for (ITimestampBased &tsObj : this->container()) { tsObj.setCurrentUtcTime(); }
141  }
142 
144  void setUtcTime(qint64 msSinceEpoch)
145  {
146  for (ITimestampBased &tsObj : this->container()) { tsObj.setMSecsSinceEpoch(msSinceEpoch); }
147  }
148 
151  {
152  for (ITimestampBased &tsObj : this->container())
153  {
154  if (tsObj.hasValidTimestamp()) { continue; }
155  tsObj.setCurrentUtcTime();
156  }
157  }
158 
160  QDateTime latestTimestamp() const
161  {
162  if (this->container().isEmpty()) { return {}; }
163  return this->latestObject().getUtcTimestamp();
164  }
165 
168  {
169  const QDateTime dt(latestTimestamp());
170  return dt.isValid() ? dt.toMSecsSinceEpoch() : -1;
171  }
172 
174  QDateTime oldestTimestamp() const
175  {
176  if (this->container().isEmpty()) { return QDateTime(); }
177  return this->oldestObject().getUtcTimestamp();
178  }
179 
182  {
183  const QDateTime dt(oldestTimestamp());
184  return dt.isValid() ? dt.toMSecsSinceEpoch() : -1;
185  }
186 
188  OBJ latestObject() const
189  {
190  if (this->container().isEmpty()) { return OBJ(); }
191  const auto latest =
192  std::max_element(this->container().begin(), this->container().end(), [](const OBJ &a, const OBJ &b) {
193  return a.getMSecsSinceEpoch() < b.getMSecsSinceEpoch();
194  });
195  return *latest;
196  }
197 
199  OBJ oldestObject() const
200  {
201  if (this->container().isEmpty()) { return OBJ(); }
202  const auto oldest =
203  std::min_element(this->container().begin(), this->container().end(), [](const OBJ &a, const OBJ &b) {
204  return a.getMSecsSinceEpoch() < b.getMSecsSinceEpoch();
205  });
206  return *oldest;
207  }
208 
210  int removeBefore(const QDateTime &dateTime) { return this->removeBefore(dateTime.toMSecsSinceEpoch()); }
211 
213  int removeBefore(qint64 msSinceEpoch)
214  {
215  return this->container().removeIf([&](const OBJ &obj) { return obj.isOlderThan(msSinceEpoch); });
216  }
217 
219  int removeOlderThanNowMinusOffset(qint64 offsetMs)
220  {
221  const qint64 epoch = QDateTime::currentMSecsSinceEpoch() - offsetMs;
222  return this->container().removeIf([&](const OBJ &obj) { return obj.isOlderThan(epoch); });
223  }
224 
227  {
228  this->container().sortOldestFirst();
229  this->container().reverse();
230  }
231 
233  void sortOldestFirst() { this->container().sort(predicates::MemberLess(&OBJ::getMSecsSinceEpoch)); }
234 
236  void push_frontKeepLatestFirst(const OBJ &value, bool replaceSameTimestamp = true, int maxElements = -1)
237  {
238  Q_ASSERT_X(maxElements < 0 || maxElements > 1, Q_FUNC_INFO, "Max.value wrong range");
239  CONTAINER &c = this->container();
240  if (replaceSameTimestamp && !c.isEmpty() && c[0].getMSecsSinceEpoch() == value.getMSecsSinceEpoch())
241  {
242  c[0] = value;
243  if (maxElements > 0) { c.truncate(maxElements); }
244  }
245  else
246  {
247  if (maxElements > 0) { c.truncate(maxElements - 1); }
248  const bool needSort = !c.isEmpty() && value.isOlderThan(c.front());
249  c.push_front(value);
250  if (needSort) { ITimestampObjectList::sortLatestFirst(); }
251  }
252 
253  // crosscheck
255  {
256  Q_ASSERT_X(this->isSortedLatestFirst(), Q_FUNC_INFO, "Wrong sort order");
257  }
258  }
259 
262  void push_backIncreaseTimestamp(const OBJ &newObject)
263  {
264  if (this->container().isEmpty())
265  {
266  this->container().push_back(newObject);
267  return;
268  }
269  const qint64 newMs = newObject.getMSecsSinceEpoch();
270  const qint64 oldMs = this->container().back().getMSecsSinceEpoch();
271  if (newMs > oldMs)
272  {
273  this->container().push_back(newObject);
274  return;
275  }
276  this->push_backOverrideTimestamp(newObject, oldMs + 1);
277  }
278 
280  void push_backOverrideTimestamp(const OBJ &newObject, qint64 newTsMsSinceEpoch)
281  {
282  OBJ newObjectCopy(newObject);
283  newObjectCopy.setMSecsSinceEpoch(newTsMsSinceEpoch);
284  this->container().push_back(newObjectCopy);
285  }
286 
288  void setNewTimestampStartingLast(qint64 startTimeStampMs, qint64 deltaTimeMs)
289  {
290  if (this->container().isEmpty()) { return; }
291  qint64 currentMs = startTimeStampMs;
292  for (auto it = this->container().rbegin(); it != this->container().rend(); ++it)
293  {
294  it->setMSecsSinceEpoch(currentMs);
295  currentMs += deltaTimeMs;
296  }
297  }
298 
300  int replaceIfSameTimestamp(const OBJ &newObject)
301  {
302  int c = 0;
303  for (OBJ &obj : this->container())
304  {
305  if (obj.getMSecsSinceEpoch() == newObject.getMSecsSinceEpoch())
306  {
307  obj = newObject;
308  c++;
309  }
310  }
311  return c;
312  }
313 
316  bool isSortedLatestLast() const
317  {
318  if (this->container().size() < 2) { return true; }
319  qint64 max = -1;
320  for (const ITimestampBased &obj : this->container())
321  {
322  if (!obj.hasValidTimestamp()) { return false; }
323  if (obj.getMSecsSinceEpoch() < max) { return false; }
324  max = obj.getMSecsSinceEpoch();
325  }
326  return true;
327  }
328 
331  bool isSortedLatestFirst() const
332  {
333  if (this->container().size() < 2) { return true; }
334  qint64 min = std::numeric_limits<qint64>::max();
335  for (const ITimestampBased &obj : this->container())
336  {
337  if (!obj.hasValidTimestamp()) { return false; }
338  if (obj.getMSecsSinceEpoch() > min) { return false; }
339  min = obj.getMSecsSinceEpoch();
340  }
341  return true;
342  }
343 
345  void addMsecs(qint64 msToAdd)
346  {
347  if (msToAdd == 0) { return; }
348  for (ITimestampBased &obj : this->container()) { obj.addMsecs(msToAdd); }
349  }
350 
353 
357  {
359  mmm.reset();
360  const CONTAINER &container = this->container();
361  if (container.size() < 2) { return mmm; }
362 
363  // Do not confuse with adjusted sort hint!
364  if (container.m_tsSortHint == NoTimestampSortHint)
365  {
366  CONTAINER copy(container);
367  copy.sortLatestFirst();
368  copy.m_tsSortHint = TimestampLatestFirst;
369  return copy.getTimestampDifferenceMinMaxMean();
370  }
371 
372  mmm.max = std::numeric_limits<qint64>::min();
373  mmm.min = std::numeric_limits<qint64>::max();
374  qint64 mean = 0;
375  int c = 0;
376  OBJ last;
377 
378  for (const OBJ &object : container)
379  {
380  if (c > 0)
381  {
382  const ITimestampBased &l = last;
383  const ITimestampBased &o = object;
384  const qint64 diff = l.getAbsTimeDifferenceMs(o);
385  if (diff > mmm.max) { mmm.max = diff; }
386  if (diff < mmm.min) { mmm.min = diff; }
387  mean += diff;
388  }
389  c++;
390  last = object;
391  }
392 
393  mmm.mean = mean / c;
394  return mmm;
395  }
396 
397  protected:
399  ITimestampObjectList() = default;
400 
402  const CONTAINER &container() const { return static_cast<const CONTAINER &>(*this); }
403 
405  CONTAINER &container() { return static_cast<CONTAINER &>(*this); }
406 
407  HintTimestampSort m_tsSortHint = NoTimestampSortHint;
408  };
409 
412  template <class OBJ, class CONTAINER>
414  {
415  static_assert(std::is_base_of_v<ITimestampWithOffsetBased, OBJ>, "OBJ needs to implement ITimestampBased");
416 
417  public:
420  {
421  NoAdjustedTimestampSortHint,
422  AdjustedTimestampLatestFirst
423  };
424 
427  {
428  this->container().sortAdjustedOldestFirst();
429  this->container().reverse();
430  }
431 
434  {
435  CONTAINER copy(this->container());
436  copy.sortAdjustedLatestFirst();
437  return copy;
438  }
439 
441  CONTAINER getLatestAdjustedTwoObjects(bool alreadySortedLatestFirst = false) const
442  {
443  if (this->container().size() < 2) { return CONTAINER(); }
444  CONTAINER copy(alreadySortedLatestFirst ? this->container() :
446  copy.truncate(2);
447  return copy;
448  }
449 
452  {
453  this->container().sort(predicates::MemberLess(&OBJ::getAdjustedMSecsSinceEpoch));
454  }
455 
458  {
459  for (const ITimestampWithOffsetBased &obj : this->container())
460  {
461  if (obj.getTimeOffsetMs() <= 0) { return true; }
462  }
463  return false;
464  }
465 
468  {
469  for (const ITimestampWithOffsetBased &obj : this->container())
470  {
471  if (obj.getTimeOffsetMs() < 0) { return true; }
472  }
473  return false;
474  }
475 
477  void addMsecsToOffset(qint64 msToAdd)
478  {
479  for (ITimestampWithOffsetBased &obj : this->container()) { obj.addMsecsToOffsetTime(msToAdd); }
480  }
481 
483  void push_frontKeepLatestAdjustedFirst(const OBJ &value, bool replaceSameTimestamp = true, int maxElements = -1)
484  {
485  Q_ASSERT_X(maxElements < 0 || maxElements > 1, Q_FUNC_INFO, "Max.value wrong range");
486  CONTAINER &c = this->container();
487  if (replaceSameTimestamp && !c.isEmpty() && c[0].getMSecsSinceEpoch() == value.getMSecsSinceEpoch())
488  {
489  c[0] = value;
490  if (maxElements > 0) { c.truncate(maxElements); }
491  return;
492  }
493 
494  if (maxElements > 0) { c.truncate(maxElements - 1); }
495  const bool needSort = !c.isEmpty() && value.isOlderThanAdjusted(c.front());
496  c.push_front(value);
498  }
499 
502  void push_frontKeepLatestFirstAdjustOffset(const OBJ &value, bool replaceSameTimestamp = true,
503  int maxElements = -1)
504  {
506  maxElements);
507 
508  // now sorted by timestamp
509  // this reflects normally the incoming order
510  // ts
511  // 8: os 2 adj 12 => min os 4
512  // 6: os 2 adj 11 => min os 5
513  // 5: os 5 adj 10
514  // 0: os 5 adj 5
515  CONTAINER &c = this->container();
516  if (c.size() < 2) { return; }
517  ITimestampWithOffsetBased &front = c.front();
518  const ITimestampWithOffsetBased &second = c[1];
519  if (!front.isNewerThanAdjusted(second))
520  {
521  // const qint64 minOs = qMin(front.getTimeOffsetMs(), second.getTimeOffsetMs());
522  const qint64 minReqOs =
523  second.getAdjustedMSecsSinceEpoch() - front.getMSecsSinceEpoch(); // minimal required
524  const qint64 avgOs = (front.getTimeOffsetMs() + second.getTimeOffsetMs()) / 2;
525  const qint64 os = qMax(minReqOs + 1, avgOs); // at least +1, as value must be > (greater)
526  front.setTimeOffsetMs(os);
527  }
528 
530  {
531  SWIFT_VERIFY_X(front.isNewerThanAdjusted(second), Q_FUNC_INFO, "Front/second timestamp");
532  SWIFT_VERIFY_X(this->isSortedAdjustedLatestFirst(), Q_FUNC_INFO, "Wrong sort order");
533  }
534  }
535 
537  void push_frontKeepLatestFirstIgnoreOverlapping(const OBJ &value, bool replaceSameTimestamp = true,
538  int maxElements = -1)
539  {
540  CONTAINER &c = this->container();
541  if (c.size() > 1)
542  {
543  const ITimestampWithOffsetBased front = c.front();
544  if (value.getAdjustedMSecsSinceEpoch() <= front.getAdjustedMSecsSinceEpoch()) { return; }
545  }
547  maxElements);
548  }
549 
551  void prefillLatestAdjustedFirst(const OBJ &value, int elements, qint64 deltaTimeMs = -1)
552  {
553  this->container().clear();
554  const qint64 osTime = value.getTimeOffsetMs();
555  const qint64 os = -1 * qAbs(deltaTimeMs < 0 ? osTime : deltaTimeMs);
557  {
558  SWIFT_VERIFY_X(os < 0, Q_FUNC_INFO, "Need negative offset time to prefill time");
559  }
560  this->container().push_front(value);
561  for (int i = 1; i < elements; i++)
562  {
563  OBJ copy(value);
564  copy.addMsecs(os * i);
565  this->container().push_back(copy);
566  }
567  this->setAdjustedSortHint(ITimestampWithOffsetObjectList::AdjustedTimestampLatestFirst);
568  }
569 
573  {
574  if (this->container().isEmpty()) { return false; }
575  if (this->container().size() < 2) { return true; }
576  qint64 max = -1;
577  for (const ITimestampWithOffsetBased &obj : this->container())
578  {
579  if (!obj.hasValidTimestamp()) { return false; }
580  if (obj.getAdjustedMSecsSinceEpoch() < max) { return false; }
581  max = obj.getAdjustedMSecsSinceEpoch();
582  }
583  return true;
584  }
585 
589  {
590  if (this->container().size() < 2) { return true; }
591  qint64 min = std::numeric_limits<qint64>::max();
592  for (const ITimestampWithOffsetBased &obj : this->container())
593  {
594  if (!obj.hasValidTimestamp()) { return false; }
595  if (obj.getAdjustedMSecsSinceEpoch() > min) { return false; }
596  min = obj.getAdjustedMSecsSinceEpoch();
597  }
598  return true;
599  }
600 
602  CONTAINER findAfterAdjusted(qint64 msSinceEpoch) const
603  {
604  return this->container().findBy(
605  [&](const ITimestampWithOffsetBased &obj) { return obj.isNewerThanAdjusted(msSinceEpoch); });
606  }
607 
609  OBJ findObjectAfterAdjustedOrDefault(qint64 msSinceEpoch) const
610  {
611  const CONTAINER after = this->findAfterAdjusted(msSinceEpoch);
612  if (after.isEmpty()) { return OBJ(); }
613  return after.oldestAdjustedObject();
614  }
615 
617  CONTAINER findBeforeAdjusted(qint64 msSinceEpoch) const
618  {
619  return this->container().findBy(
620  [&](const ITimestampWithOffsetBased &obj) { return obj.isOlderThanAdjusted(msSinceEpoch); });
621  }
622 
624  OBJ findObjectBeforeAdjustedOrDefault(qint64 msSinceEpoch) const
625  {
626  const CONTAINER before = this->findBeforeAdjusted(msSinceEpoch);
627  if (before.isEmpty()) { return OBJ(); }
628  return before.latestAdjustedObject();
629  }
630 
632  OBJ findClosestTimeDistanceAdjusted(qint64 msSinceEpoch) const
633  {
634  if (this->container().isEmpty()) { return OBJ(); }
635  const auto closest =
636  std::min_element(this->container().cbegin(), this->container().cend(),
637  [=](const ITimestampWithOffsetBased &a, const ITimestampWithOffsetBased &b) {
638  return qAbs(a.getAdjustedTimeDifferenceMs(msSinceEpoch)) <
639  qAbs(b.getAdjustedTimeDifferenceMs(msSinceEpoch));
640  });
641  return *closest;
642  }
643 
646  {
647  if (this->container().isEmpty()) { return OBJ(); }
648  if (this->container().m_tsAdjustedSortHint == AdjustedTimestampLatestFirst)
649  {
650  return this->container().front();
651  }
652  const auto latest =
653  std::max_element(this->container().begin(), this->container().end(), [](const OBJ &a, const OBJ &b) {
654  return a.getAdjustedMSecsSinceEpoch() < b.getAdjustedMSecsSinceEpoch();
655  });
656  return *latest;
657  }
658 
661  {
662  if (this->container().isEmpty()) { return OBJ(); }
663  if (this->container().m_tsAdjustedSortHint == AdjustedTimestampLatestFirst)
664  {
665  return this->container().back();
666  }
667  const auto oldest =
668  std::min_element(this->container().begin(), this->container().end(), [](const OBJ &a, const OBJ &b) {
669  return a.getAdjustedMSecsSinceEpoch() < b.getAdjustedMSecsSinceEpoch();
670  });
671  return *oldest;
672  }
673 
675  QDateTime latestAdjustedTimestamp() const
676  {
677  if (this->container().isEmpty()) { return QDateTime(); }
678  return this->latestAdjustedObject().getUtcTimestamp();
679  }
680 
682  QDateTime oldestAdjustedTimestamp() const
683  {
684  if (this->container().isEmpty()) { return QDateTime(); }
685  return this->oldestAdjustedObject().getUtcTimestamp();
686  }
687 
690  {
691  if (this->container().isEmpty()) { return -1; }
692  const QDateTime dt(this->latestAdjustedTimestamp());
693  return dt.isValid() ? dt.toMSecsSinceEpoch() : -1;
694  }
695 
698  {
699  if (this->container().isEmpty()) { return -1; }
700  const QDateTime dt(oldestAdjustedTimestamp());
701  return dt.isValid() ? dt.toMSecsSinceEpoch() : -1;
702  }
703 
705  void setAdjustedSortHint(HintAdjustedTimestampSort hint) { this->container().m_tsAdjustedSortHint = hint; }
706 
710  {
712  mmm.reset();
713  const CONTAINER &container = this->container();
714  if (container.size() < 1) { return mmm; }
715 
716  mmm.max = std::numeric_limits<qint64>::min();
717  mmm.min = std::numeric_limits<qint64>::max();
718  qint64 mean = 0;
719  int c = 0;
720 
721  for (const ITimestampWithOffsetBased &object : container)
722  {
723  if (!object.hasNonZeroOffsetTime()) { continue; }
724  const qint64 os = object.getTimeOffsetMs();
725  if (os > mmm.max) { mmm.max = os; }
726  if (os < mmm.min) { mmm.min = os; }
727  mean += os;
728  c++;
729  }
730 
731  if (c > 0) { mmm.mean = mean / c; }
732  return mmm;
733  }
734 
735  protected:
738 
739  HintAdjustedTimestampSort m_tsAdjustedSortHint = NoAdjustedTimestampSortHint;
740  };
741 } // namespace swift::misc
742 
743 #endif // SWIFT_MISC_TIMESTAMPOBJECTLIST_H
static bool isLocalDeveloperDebugBuild()
Local build for developers.
Entity with timestamp.
qint64 getMSecsSinceEpoch() const
Timestamp as ms value.
qint64 getTimeDifferenceMs(qint64 compareTime) const
Time difference in ms.
qint64 getAbsTimeDifferenceMs(qint64 compareTime) const
Time difference in ms.
List of objects with timestamp. Such objects should implement.
OBJ findObjectBeforeOrDefault(qint64 msSinceEpoch) const
Object before timestamp or default (older)
qint64 latestTimestampMsecsSinceEpoch() const
Latest timestamp.
QDateTime latestTimestamp() const
Latest timestamp.
void push_backOverrideTimestamp(const OBJ &newObject, qint64 newTsMsSinceEpoch)
Push back, but set new timestamp.
void setSortHint(HintTimestampSort hint)
Set the hint.
HintTimestampSort m_tsSortHint
sort hint
void sortOldestFirst()
Sort by timestamp.
OBJ oldestObject() const
Latest object.
int removeBefore(qint64 msSinceEpoch)
Remove objects with timestamp before dateTime.
CONTAINER findBeforeNowMinusOffset(qint64 msOffset) const
List of objects before now - offset.
int replaceIfSameTimestamp(const OBJ &newObject)
Replace if an object has the same timestamp.
CONTAINER findAfter(const QDateTime &dateTime) const
List of objects after dateTime (newer)
void addMsecs(qint64 msToAdd)
Adds a time to all values.
const CONTAINER & container() const
Container.
qint64 oldestTimestampMsecsSinceEpoch() const
Oldest timestamp.
CONTAINER findBeforeAndRemove(qint64 msSinceEpoch)
Get objects before msSinceEpoch and remove those.
MillisecondsMinMaxMean getTimestampDifferenceMinMaxMean() const
Difference of timestamp values.
CONTAINER findAfter(qint64 msSinceEpoch) const
List of objects after msSinceEpoch (newer)
ITimestampObjectList()=default
Constructor.
void setCurrentUtcTime()
Set all timestamps to now.
OBJ findObjectAfterOrDefault(qint64 msSinceEpoch) const
List of objects after msSinceEpoch (newer)
void setInvalidTimestampsToCurrentUtcTime()
Set invalid timestamps to now.
OBJ latestObject() const
Latest object.
void sortLatestFirst()
Sort by timestamp.
HintTimestampSort
Hint if the list is sorted.
void push_backIncreaseTimestamp(const OBJ &newObject)
Push back and increase the timestamp at least by +1ms if equal to last element.
int removeBefore(const QDateTime &dateTime)
Remove objects with timestamp before dateTime.
int removeOlderThanNowMinusOffset(qint64 offsetMs)
Remove objects older than seconds.
bool isSortedLatestLast() const
Is completely sorted: latest last.
void push_frontKeepLatestFirst(const OBJ &value, bool replaceSameTimestamp=true, int maxElements=-1)
Insert as first element by keeping maxElements and the latest first.
QDateTime oldestTimestamp() const
Oldest timestamp.
CONTAINER findBefore(const QDateTime &dateTime) const
List of objects before dateTime (older)
CONTAINER findBefore(qint64 msSinceEpoch) const
List of objects before msSinceEpoch (older)
bool hasInvalidTimestamps() const
Has invalid timestamp.
void setUtcTime(qint64 msSinceEpoch)
Set all timestamps to given time.
CONTAINER findInvalidTimestamps() const
Objects without valid timestamp.
bool isSortedLatestFirst() const
Is completely sorted: latest last.
void setNewTimestampStartingLast(qint64 startTimeStampMs, qint64 deltaTimeMs)
Set new timestamps starting with the last element.
CONTAINER findAfterNowMinusOffset(qint64 msOffset) const
List of objects before now - offset.
OBJ findClosestTimeDistance(qint64 msSinceEpoch) const
Find closest (or default)
qint64 getAdjustedMSecsSinceEpoch() const
Timestamp with offset added for interpolation.
qint64 getTimeOffsetMs() const
Milliseconds to add to timestamp for interpolation.
bool isNewerThanAdjusted(const ITimestampWithOffsetBased &otherTimestampObj) const
Is this newer than other?
bool isOlderThanAdjusted(const ITimestampWithOffsetBased &otherTimestampObj) const
Is this older than other?
qint64 getAdjustedTimeDifferenceMs(qint64 compareTime) const
Time difference in ms (this -> compare)
void setTimeOffsetMs(qint64 offset)
Milliseconds to add to timestamp for interpolation.
List of objects with timestamp and offset. Such objects should implement.
OBJ findClosestTimeDistanceAdjusted(qint64 msSinceEpoch) const
Closest adjusted time difference.
bool containsZeroOrNegativeOffsetTime() const
Any negative or zero offset time?
CONTAINER getLatestAdjustedTwoObjects(bool alreadySortedLatestFirst=false) const
Get the latest 2 values.
HintAdjustedTimestampSort
Hint if the list is sorted.
QDateTime oldestAdjustedTimestamp() const
Oldest adjusted timestamp.
bool isSortedAdjustedLatestFirst() const
Is completely sorted: latest last.
OBJ findObjectBeforeAdjustedOrDefault(qint64 msSinceEpoch) const
Object before timestamp (older)
void setAdjustedSortHint(HintAdjustedTimestampSort hint)
Set the hint.
CONTAINER findBeforeAdjusted(qint64 msSinceEpoch) const
List of objects before msSinceEpoch (older)
OBJ latestAdjustedObject() const
Latest adjusted object.
bool isSortedAdjustedLatestLast() const
Is completely sorted: latest last.
MillisecondsMinMaxMean getOffsetMinMaxMean() const
Difference of timestamp values.
void addMsecsToOffset(qint64 msToAdd)
Adds a time to all offset values.
void push_frontKeepLatestAdjustedFirst(const OBJ &value, bool replaceSameTimestamp=true, int maxElements=-1)
Insert as first element by keeping maxElements and the latest first.
qint64 oldestAdjustedTimestampMsecsSinceEpoch() const
Oldest adjusted timestamp.
void sortAdjustedLatestFirst()
Sort by adjusted timestamp.
bool containsNegativeOffsetTime() const
Any negative offset time?
CONTAINER getSortedAdjustedLatestFirst() const
As sorted copy.
void prefillLatestAdjustedFirst(const OBJ &value, int elements, qint64 deltaTimeMs=-1)
Prefill with elements.
QDateTime latestAdjustedTimestamp() const
Latest adjusted timestamp.
OBJ oldestAdjustedObject() const
Oldest adjusted object.
void push_frontKeepLatestFirstAdjustOffset(const OBJ &value, bool replaceSameTimestamp=true, int maxElements=-1)
Insert as first element by keeping maxElements and the latest first.
HintAdjustedTimestampSort m_tsAdjustedSortHint
sort hint
void push_frontKeepLatestFirstIgnoreOverlapping(const OBJ &value, bool replaceSameTimestamp=true, int maxElements=-1)
Add value, but ignore overlapping (past) values.
qint64 latestAdjustedTimestampMsecsSinceEpoch() const
Latest adjusted timestamp.
CONTAINER findAfterAdjusted(qint64 msSinceEpoch) const
List of objects after msSinceEpoch (newer)
OBJ findObjectAfterAdjustedOrDefault(qint64 msSinceEpoch) const
List of objects after msSinceEpoch (newer)
ITimestampWithOffsetObjectList()=default
Constructor.
void sortAdjustedOldestFirst()
Sort by adjusted timestamp.
auto MemberLess(Ts... vs)
Predicate which compares the return values of some member functions of two objects.
Definition: predicates.h:43
Free functions in swift::misc.
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:332
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
Definition: lockfree.h:338
Milliseconds minimum/maximum/mean.
QString asString() const
As string.
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26