@@ -168,6 +168,7 @@ DiscreteTraject0ry<Frame>::NewSegment() {
168
168
segment_by_left_endpoint_.end (), last_time, new_segment_sit);
169
169
}
170
170
171
+ DCHECK_OK (ConsistencyStatus ());
171
172
return new_self;
172
173
}
173
174
@@ -185,6 +186,7 @@ DiscreteTraject0ry<Frame>::DetachSegments(SegmentIterator const begin) {
185
186
/* to=*/ detached,
186
187
/* to_segments_begin=*/ detached.segments_ ->begin ());
187
188
189
+ DCHECK_OK (ConsistencyStatus ());
188
190
return detached;
189
191
}
190
192
@@ -218,12 +220,30 @@ DiscreteTraject0ry<Frame>::AttachSegments(
218
220
/* to=*/ *this ,
219
221
/* to_segments_begin=*/ end_before_splice);
220
222
223
+ DCHECK_OK (ConsistencyStatus ());
221
224
return SegmentIterator (segments_.get (), end_before_splice);
222
225
}
223
226
224
227
template <typename Frame>
225
228
void DiscreteTraject0ry<Frame>::DeleteSegments(SegmentIterator const begin) {
226
229
segments_->erase (begin.iterator (), segments_->end ());
230
+ if (segments_->empty ()) {
231
+ segment_by_left_endpoint_.clear ();
232
+ } else {
233
+ auto const last_segment = --segments_->end ();
234
+ if (last_segment->empty ()) {
235
+ segment_by_left_endpoint_.clear ();
236
+ } else {
237
+ // If there remains a non-empty segment, update the time-to-segment map
238
+ // with for its time, and delete the rest.
239
+ auto const & [leit, _] = segment_by_left_endpoint_.insert_or_assign (
240
+ last_segment->front ().time , last_segment);
241
+ segment_by_left_endpoint_.erase (std::next (leit),
242
+ segment_by_left_endpoint_.end ());
243
+ }
244
+ }
245
+
246
+ DCHECK_OK (ConsistencyStatus ());
227
247
}
228
248
229
249
template <typename Frame>
@@ -246,6 +266,8 @@ void DiscreteTraject0ry<Frame>::ForgetAfter(Instant const& t) {
246
266
segment_by_left_endpoint_.erase (std::next (leit),
247
267
segment_by_left_endpoint_.end ());
248
268
}
269
+
270
+ DCHECK_OK (ConsistencyStatus ());
249
271
}
250
272
251
273
template <typename Frame>
@@ -277,6 +299,8 @@ void DiscreteTraject0ry<Frame>::ForgetBefore(Instant const& t) {
277
299
segment_by_left_endpoint_.insert_or_assign (segment_by_left_endpoint_.begin (),
278
300
sit->front ().time ,
279
301
sit);
302
+
303
+ DCHECK_OK (ConsistencyStatus ());
280
304
}
281
305
282
306
template <typename Frame>
@@ -303,6 +327,8 @@ void DiscreteTraject0ry<Frame>::Append(
303
327
CHECK (!sit->empty ()) << " Empty segment at " << t;
304
328
}
305
329
sit->Append (t, degrees_of_freedom);
330
+
331
+ DCHECK_OK (ConsistencyStatus ());
306
332
}
307
333
308
334
template <typename Frame>
@@ -403,7 +429,7 @@ DiscreteTraject0ry<Frame>::ReadFromMessage(
403
429
LOG_IF (WARNING, is_pre_ζήνων) << " Reading pre-Ζήνων DiscreteTrajectory" ;
404
430
ReadFromPreΖήνωνMessage (
405
431
message, tracked, /* fork_point=*/ std::nullopt, trajectory);
406
- CHECK_OK (trajectory.ValidateConsistency ());
432
+ CHECK_OK (trajectory.ConsistencyStatus ());
407
433
return trajectory;
408
434
}
409
435
@@ -444,7 +470,7 @@ DiscreteTraject0ry<Frame>::ReadFromMessage(
444
470
trajectory.segment_by_left_endpoint_ .end (), t, sit);
445
471
}
446
472
447
- CHECK_OK (trajectory.ValidateConsistency ());
473
+ CHECK_OK (trajectory.ConsistencyStatus ());
448
474
return trajectory;
449
475
}
450
476
@@ -477,7 +503,7 @@ DiscreteTraject0ry<Frame>::FindSegment(
477
503
}
478
504
479
505
template <typename Frame>
480
- absl::Status DiscreteTraject0ry<Frame>::ValidateConsistency () const {
506
+ absl::Status DiscreteTraject0ry<Frame>::ConsistencyStatus () const {
481
507
if (segments_->size () < segment_by_left_endpoint_.size ()) {
482
508
return absl::InternalError (absl::StrCat (" Size mismatch " ,
483
509
segments_->size (),
@@ -539,25 +565,27 @@ absl::Status DiscreteTraject0ry<Frame>::ValidateConsistency() const {
539
565
// Great care is required here because the DiscreteTrajectoryIterator will
540
566
// "helpfully" paper over differences in degrees of freedom as long as the
541
567
// times match. We must look at the endpoints of the timeline explicitly.
542
- auto const timeline_rbegin = --sit->timeline_end ();
543
- auto const timeline_begin = std::next (sit)->timeline_begin ();
544
- if (timeline_rbegin->time != timeline_begin->time ) {
545
- return absl::InternalError (
546
- absl::StrCat (" Duplicated time mismatch " ,
547
- DebugString (timeline_rbegin->time ),
548
- " and " ,
549
- DebugString (timeline_begin->time ),
550
- " for segment #" ,
551
- i));
552
- } else if (timeline_rbegin->degrees_of_freedom !=
553
- timeline_begin->degrees_of_freedom ) {
554
- return absl::InternalError (
555
- absl::StrCat (" Duplicated degrees of freedom mismatch " ,
556
- DebugString (timeline_rbegin->degrees_of_freedom ),
557
- " and " ,
558
- DebugString (timeline_begin->degrees_of_freedom ),
559
- " for segment #" ,
560
- i));
568
+ if (!sit->timeline_empty ()) {
569
+ auto const timeline_rbegin = --sit->timeline_end ();
570
+ auto const timeline_begin = std::next (sit)->timeline_begin ();
571
+ if (timeline_rbegin->time != timeline_begin->time ) {
572
+ return absl::InternalError (
573
+ absl::StrCat (" Duplicated time mismatch " ,
574
+ DebugString (timeline_rbegin->time ),
575
+ " and " ,
576
+ DebugString (timeline_begin->time ),
577
+ " for segment #" ,
578
+ i));
579
+ } else if (timeline_rbegin->degrees_of_freedom !=
580
+ timeline_begin->degrees_of_freedom ) {
581
+ return absl::InternalError (
582
+ absl::StrCat (" Duplicated degrees of freedom mismatch " ,
583
+ DebugString (timeline_rbegin->degrees_of_freedom ),
584
+ " and " ,
585
+ DebugString (timeline_begin->degrees_of_freedom ),
586
+ " for segment #" ,
587
+ i));
588
+ }
561
589
}
562
590
}
563
591
}
@@ -591,12 +619,14 @@ void DiscreteTraject0ry<Frame>::AdjustAfterSplicing(
591
619
// insert it again.
592
620
from.segment_by_left_endpoint_ .erase (from_leit,
593
621
from.segment_by_left_endpoint_ .end ());
594
- if (!from.empty ()) {
622
+ if (!from.segments_ -> empty ()) {
595
623
auto const last_segment = --from.segments_ ->end ();
596
- from.segment_by_left_endpoint_ .insert_or_assign (
597
- from.segment_by_left_endpoint_ .end (),
598
- last_segment->front ().time ,
599
- last_segment);
624
+ if (!last_segment->empty ()) {
625
+ from.segment_by_left_endpoint_ .insert_or_assign (
626
+ from.segment_by_left_endpoint_ .end (),
627
+ last_segment->front ().time ,
628
+ last_segment);
629
+ }
600
630
}
601
631
}
602
632
0 commit comments