1#![allow(missing_docs)]
23
24mod composite;
25mod entry;
26mod mutable;
27mod readonly;
28mod rev_walk;
29mod rev_walk_queue;
30pub mod revset_engine;
31mod revset_graph_iterator;
32mod store;
33
34pub use self::composite::AsCompositeIndex;
35pub use self::composite::CompositeIndex;
36pub use self::composite::IndexLevelStats;
37pub use self::composite::IndexStats;
38pub use self::entry::IndexEntry;
39pub use self::entry::IndexPosition;
40pub use self::mutable::DefaultMutableIndex;
41pub use self::readonly::DefaultReadonlyIndex;
42pub use self::readonly::ReadonlyIndexLoadError;
43pub use self::store::DefaultIndexStore;
44pub use self::store::DefaultIndexStoreError;
45pub use self::store::DefaultIndexStoreInitError;
46
47#[cfg(test)]
48mod tests {
49 use std::sync::Arc;
50
51 use itertools::Itertools as _;
52 use smallvec::smallvec_inline;
53 use test_case::test_case;
54
55 use super::composite::DynIndexSegment;
56 use super::composite::IndexSegment as _;
57 use super::entry::SmallIndexPositionsVec;
58 use super::mutable::MutableIndexSegment;
59 use super::*;
60 use crate::backend::ChangeId;
61 use crate::backend::CommitId;
62 use crate::default_index::entry::LocalPosition;
63 use crate::default_index::entry::SmallLocalPositionsVec;
64 use crate::index::Index as _;
65 use crate::object_id::HexPrefix;
66 use crate::object_id::ObjectId as _;
67 use crate::object_id::PrefixResolution;
68 use crate::tests::new_temp_dir;
69
70 fn commit_id_generator() -> impl FnMut() -> CommitId {
72 let mut iter = (1_u128..).map(|n| CommitId::new(n.to_le_bytes().into()));
73 move || iter.next().unwrap()
74 }
75
76 fn change_id_generator() -> impl FnMut() -> ChangeId {
78 let mut iter = (1_u128..).map(|n| ChangeId::new(n.to_le_bytes().into()));
79 move || iter.next().unwrap()
80 }
81
82 #[test_case(false; "memory")]
83 #[test_case(true; "file")]
84 fn index_empty(on_disk: bool) {
85 let temp_dir = new_temp_dir();
86 let mutable_segment = MutableIndexSegment::full(3, 16);
87 let index_segment: Box<DynIndexSegment> = if on_disk {
88 let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
89 Box::new(Arc::try_unwrap(saved_index).unwrap())
90 } else {
91 Box::new(mutable_segment)
92 };
93 let index = CompositeIndex::new(index_segment.as_ref());
94
95 let stats = index.stats();
97 assert_eq!(stats.num_commits, 0);
98 assert_eq!(stats.num_heads, 0);
99 assert_eq!(stats.max_generation_number, 0);
100 assert_eq!(stats.num_merges, 0);
101 assert_eq!(stats.num_changes, 0);
102 assert_eq!(index.num_commits(), 0);
103 assert!(index.entry_by_id(&CommitId::from_hex("000000")).is_none());
105 assert!(index.entry_by_id(&CommitId::from_hex("aaa111")).is_none());
106 assert!(index.entry_by_id(&CommitId::from_hex("ffffff")).is_none());
107 }
108
109 #[test_case(false; "memory")]
110 #[test_case(true; "file")]
111 fn index_root_commit(on_disk: bool) {
112 let temp_dir = new_temp_dir();
113 let mut new_change_id = change_id_generator();
114 let mut mutable_segment = MutableIndexSegment::full(3, 16);
115 let id_0 = CommitId::from_hex("000000");
116 let change_id0 = new_change_id();
117 mutable_segment.add_commit_data(id_0.clone(), change_id0.clone(), &[]);
118 let index_segment: Box<DynIndexSegment> = if on_disk {
119 let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
120 Box::new(Arc::try_unwrap(saved_index).unwrap())
121 } else {
122 Box::new(mutable_segment)
123 };
124 let index = CompositeIndex::new(index_segment.as_ref());
125
126 let stats = index.stats();
128 assert_eq!(stats.num_commits, 1);
129 assert_eq!(stats.num_heads, 1);
130 assert_eq!(stats.max_generation_number, 0);
131 assert_eq!(stats.num_merges, 0);
132 assert_eq!(stats.num_changes, 1);
133 assert_eq!(index.num_commits(), 1);
134 assert_eq!(index.commit_id_to_pos(&id_0), Some(IndexPosition(0)));
136 assert_eq!(index.commit_id_to_pos(&CommitId::from_hex("aaaaaa")), None);
137 assert_eq!(index.commit_id_to_pos(&CommitId::from_hex("ffffff")), None);
138 let entry = index.entry_by_id(&id_0).unwrap();
140 assert_eq!(entry.position(), IndexPosition(0));
141 assert_eq!(entry.commit_id(), id_0);
142 assert_eq!(entry.change_id(), change_id0);
143 assert_eq!(entry.generation_number(), 0);
144 assert_eq!(entry.num_parents(), 0);
145 assert_eq!(entry.parent_positions(), SmallIndexPositionsVec::new());
146 assert_eq!(entry.parents().len(), 0);
147 }
148
149 #[test]
150 #[should_panic(expected = "parent commit is not indexed")]
151 fn index_missing_parent_commit() {
152 let mut new_change_id = change_id_generator();
153 let mut index = DefaultMutableIndex::full(3, 16);
154 let id_0 = CommitId::from_hex("000000");
155 let id_1 = CommitId::from_hex("111111");
156 index.add_commit_data(id_1, new_change_id(), &[id_0]);
157 }
158
159 #[test_case(false, false; "full in memory")]
160 #[test_case(false, true; "full on disk")]
161 #[test_case(true, false; "incremental in memory")]
162 #[test_case(true, true; "incremental on disk")]
163 fn index_multiple_commits(incremental: bool, on_disk: bool) {
164 let temp_dir = new_temp_dir();
165 let mut new_change_id = change_id_generator();
166 let mut mutable_segment = MutableIndexSegment::full(3, 16);
167 let id_0 = CommitId::from_hex("000000");
175 let change_id0 = new_change_id();
176 let id_1 = CommitId::from_hex("111111");
177 let change_id1 = new_change_id();
178 let id_2 = CommitId::from_hex("222222");
179 let change_id2 = change_id1.clone();
180 mutable_segment.add_commit_data(id_0.clone(), change_id0, &[]);
181 mutable_segment.add_commit_data(id_1.clone(), change_id1.clone(), &[id_0.clone()]);
182 mutable_segment.add_commit_data(id_2.clone(), change_id2.clone(), &[id_0.clone()]);
183
184 if incremental {
187 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
188 mutable_segment = MutableIndexSegment::incremental(initial_file);
189 }
190
191 let id_3 = CommitId::from_hex("333333");
192 let change_id3 = new_change_id();
193 let id_4 = CommitId::from_hex("444444");
194 let change_id4 = new_change_id();
195 let id_5 = CommitId::from_hex("555555");
196 let change_id5 = change_id3.clone();
197 mutable_segment.add_commit_data(id_3.clone(), change_id3.clone(), &[id_2.clone()]);
198 mutable_segment.add_commit_data(id_4.clone(), change_id4, &[id_1.clone()]);
199 mutable_segment.add_commit_data(id_5.clone(), change_id5, &[id_4.clone(), id_2.clone()]);
200 let index_segment: Box<DynIndexSegment> = if on_disk {
201 let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
202 Box::new(Arc::try_unwrap(saved_index).unwrap())
203 } else {
204 Box::new(mutable_segment)
205 };
206 let index = CompositeIndex::new(index_segment.as_ref());
207
208 let stats = index.stats();
210 assert_eq!(stats.num_commits, 6);
211 assert_eq!(stats.num_heads, 2);
212 assert_eq!(stats.max_generation_number, 3);
213 assert_eq!(stats.num_merges, 1);
214 assert_eq!(stats.num_changes, 4);
215 assert_eq!(index.num_commits(), 6);
216 let entry_0 = index.entry_by_id(&id_0).unwrap();
218 let entry_1 = index.entry_by_id(&id_1).unwrap();
219 let entry_2 = index.entry_by_id(&id_2).unwrap();
220 let entry_3 = index.entry_by_id(&id_3).unwrap();
221 let entry_4 = index.entry_by_id(&id_4).unwrap();
222 let entry_5 = index.entry_by_id(&id_5).unwrap();
223 assert_eq!(entry_0.position(), IndexPosition(0));
225 assert_eq!(entry_0.commit_id(), id_0);
226 assert_eq!(entry_1.position(), IndexPosition(1));
227 assert_eq!(entry_1.commit_id(), id_1);
228 assert_eq!(entry_1.change_id(), change_id1);
229 assert_eq!(entry_1.generation_number(), 1);
230 assert_eq!(entry_1.num_parents(), 1);
231 assert_eq!(
232 entry_1.parent_positions(),
233 smallvec_inline![IndexPosition(0)]
234 );
235 assert_eq!(entry_1.parents().len(), 1);
236 assert_eq!(
237 entry_1.parents().next().unwrap().position(),
238 IndexPosition(0)
239 );
240 assert_eq!(entry_2.position(), IndexPosition(2));
241 assert_eq!(entry_2.commit_id(), id_2);
242 assert_eq!(entry_2.change_id(), change_id2);
243 assert_eq!(entry_2.generation_number(), 1);
244 assert_eq!(entry_2.num_parents(), 1);
245 assert_eq!(
246 entry_2.parent_positions(),
247 smallvec_inline![IndexPosition(0)]
248 );
249 assert_eq!(entry_3.change_id(), change_id3);
250 assert_eq!(entry_3.generation_number(), 2);
251 assert_eq!(
252 entry_3.parent_positions(),
253 smallvec_inline![IndexPosition(2)]
254 );
255 assert_eq!(entry_4.position(), IndexPosition(4));
256 assert_eq!(entry_4.generation_number(), 2);
257 assert_eq!(entry_4.num_parents(), 1);
258 assert_eq!(
259 entry_4.parent_positions(),
260 smallvec_inline![IndexPosition(1)]
261 );
262 assert_eq!(entry_5.generation_number(), 3);
263 assert_eq!(entry_5.num_parents(), 2);
264 assert_eq!(
265 entry_5.parent_positions(),
266 smallvec_inline![IndexPosition(4), IndexPosition(2)]
267 );
268 assert_eq!(entry_5.parents().len(), 2);
269 assert_eq!(
270 entry_5.parents().next().unwrap().position(),
271 IndexPosition(4)
272 );
273 assert_eq!(
274 entry_5.parents().nth(1).unwrap().position(),
275 IndexPosition(2)
276 );
277 }
278
279 #[test_case(false; "in memory")]
280 #[test_case(true; "on disk")]
281 fn index_many_parents(on_disk: bool) {
282 let temp_dir = new_temp_dir();
283 let mut new_change_id = change_id_generator();
284 let mut mutable_segment = MutableIndexSegment::full(3, 16);
285 let id_0 = CommitId::from_hex("000000");
295 let id_1 = CommitId::from_hex("111111");
296 let id_2 = CommitId::from_hex("222222");
297 let id_3 = CommitId::from_hex("333333");
298 let id_4 = CommitId::from_hex("444444");
299 let id_5 = CommitId::from_hex("555555");
300 let id_6 = CommitId::from_hex("666666");
301 mutable_segment.add_commit_data(id_0.clone(), new_change_id(), &[]);
302 mutable_segment.add_commit_data(id_1.clone(), new_change_id(), &[id_0.clone()]);
303 mutable_segment.add_commit_data(id_2.clone(), new_change_id(), &[id_0.clone()]);
304 mutable_segment.add_commit_data(id_3.clone(), new_change_id(), &[id_0.clone()]);
305 mutable_segment.add_commit_data(id_4.clone(), new_change_id(), &[id_0.clone()]);
306 mutable_segment.add_commit_data(id_5.clone(), new_change_id(), &[id_0]);
307 mutable_segment.add_commit_data(
308 id_6.clone(),
309 new_change_id(),
310 &[id_1, id_2, id_3, id_4, id_5],
311 );
312 let index_segment: Box<DynIndexSegment> = if on_disk {
313 let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
314 Box::new(Arc::try_unwrap(saved_index).unwrap())
315 } else {
316 Box::new(mutable_segment)
317 };
318 let index = CompositeIndex::new(index_segment.as_ref());
319
320 let stats = index.stats();
322 assert_eq!(stats.num_commits, 7);
323 assert_eq!(stats.num_heads, 1);
324 assert_eq!(stats.max_generation_number, 2);
325 assert_eq!(stats.num_merges, 1);
326
327 let entry_6 = index.entry_by_id(&id_6).unwrap();
329 assert_eq!(entry_6.commit_id(), id_6.clone());
330 assert_eq!(entry_6.num_parents(), 5);
331 assert_eq!(
332 entry_6.parent_positions(),
333 smallvec_inline![
334 IndexPosition(1),
335 IndexPosition(2),
336 IndexPosition(3),
337 IndexPosition(4),
338 IndexPosition(5),
339 ]
340 );
341 assert_eq!(entry_6.generation_number(), 2);
342 }
343
344 #[test]
345 fn resolve_commit_id_prefix() {
346 let temp_dir = new_temp_dir();
347 let mut new_change_id = change_id_generator();
348 let mut mutable_segment = MutableIndexSegment::full(3, 16);
349
350 let id_0 = CommitId::from_hex("000000");
352 let id_1 = CommitId::from_hex("009999");
353 let id_2 = CommitId::from_hex("055488");
354 mutable_segment.add_commit_data(id_0.clone(), new_change_id(), &[]);
355 mutable_segment.add_commit_data(id_1.clone(), new_change_id(), &[]);
356 mutable_segment.add_commit_data(id_2.clone(), new_change_id(), &[]);
357
358 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
360 mutable_segment = MutableIndexSegment::incremental(initial_file);
361
362 let id_3 = CommitId::from_hex("055444");
363 let id_4 = CommitId::from_hex("055555");
364 let id_5 = CommitId::from_hex("033333");
365 mutable_segment.add_commit_data(id_3, new_change_id(), &[]);
366 mutable_segment.add_commit_data(id_4, new_change_id(), &[]);
367 mutable_segment.add_commit_data(id_5, new_change_id(), &[]);
368
369 let index = mutable_segment.as_composite();
370
371 assert_eq!(
373 index.resolve_commit_id_prefix(&HexPrefix::new(&id_0.hex()).unwrap()),
374 PrefixResolution::SingleMatch(id_0)
375 );
376 assert_eq!(
377 index.resolve_commit_id_prefix(&HexPrefix::new(&id_1.hex()).unwrap()),
378 PrefixResolution::SingleMatch(id_1)
379 );
380 assert_eq!(
381 index.resolve_commit_id_prefix(&HexPrefix::new(&id_2.hex()).unwrap()),
382 PrefixResolution::SingleMatch(id_2)
383 );
384 assert_eq!(
386 index.resolve_commit_id_prefix(&HexPrefix::new("ffffff").unwrap()),
387 PrefixResolution::NoMatch
388 );
389 assert_eq!(
390 index.resolve_commit_id_prefix(&HexPrefix::new("000001").unwrap()),
391 PrefixResolution::NoMatch
392 );
393 assert_eq!(
395 index.resolve_commit_id_prefix(&HexPrefix::new("0").unwrap()),
396 PrefixResolution::AmbiguousMatch
397 );
398 assert_eq!(
400 index.resolve_commit_id_prefix(&HexPrefix::new("009").unwrap()),
401 PrefixResolution::SingleMatch(CommitId::from_hex("009999"))
402 );
403 assert_eq!(
405 index.resolve_commit_id_prefix(&HexPrefix::new("03").unwrap()),
406 PrefixResolution::SingleMatch(CommitId::from_hex("033333"))
407 );
408 assert_eq!(
410 index.resolve_commit_id_prefix(&HexPrefix::new("0554").unwrap()),
411 PrefixResolution::AmbiguousMatch
412 );
413 }
414
415 #[test]
416 #[expect(clippy::redundant_clone)] fn neighbor_commit_ids() {
418 let temp_dir = new_temp_dir();
419 let mut new_change_id = change_id_generator();
420 let mut mutable_segment = MutableIndexSegment::full(3, 16);
421
422 let id_0 = CommitId::from_hex("000001");
424 let id_1 = CommitId::from_hex("009999");
425 let id_2 = CommitId::from_hex("055488");
426 mutable_segment.add_commit_data(id_0.clone(), new_change_id(), &[]);
427 mutable_segment.add_commit_data(id_1.clone(), new_change_id(), &[]);
428 mutable_segment.add_commit_data(id_2.clone(), new_change_id(), &[]);
429
430 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
432 mutable_segment = MutableIndexSegment::incremental(initial_file.clone());
433
434 let id_3 = CommitId::from_hex("055444");
435 let id_4 = CommitId::from_hex("055555");
436 let id_5 = CommitId::from_hex("033333");
437 mutable_segment.add_commit_data(id_3.clone(), new_change_id(), &[]);
438 mutable_segment.add_commit_data(id_4.clone(), new_change_id(), &[]);
439 mutable_segment.add_commit_data(id_5.clone(), new_change_id(), &[]);
440
441 assert_eq!(
443 initial_file.resolve_neighbor_commit_ids(&id_0),
444 (None, Some(id_1.clone())),
445 );
446 assert_eq!(
447 initial_file.resolve_neighbor_commit_ids(&id_1),
448 (Some(id_0.clone()), Some(id_2.clone())),
449 );
450 assert_eq!(
451 initial_file.resolve_neighbor_commit_ids(&id_2),
452 (Some(id_1.clone()), None),
453 );
454
455 assert_eq!(
457 initial_file.resolve_neighbor_commit_ids(&CommitId::from_hex("000000")),
458 (None, Some(id_0.clone())),
459 );
460 assert_eq!(
461 initial_file.resolve_neighbor_commit_ids(&CommitId::from_hex("000002")),
462 (Some(id_0.clone()), Some(id_1.clone())),
463 );
464 assert_eq!(
465 initial_file.resolve_neighbor_commit_ids(&CommitId::from_hex("ffffff")),
466 (Some(id_2.clone()), None),
467 );
468
469 assert_eq!(
471 mutable_segment.resolve_neighbor_commit_ids(&id_5),
472 (None, Some(id_3.clone())),
473 );
474 assert_eq!(
475 mutable_segment.resolve_neighbor_commit_ids(&id_3),
476 (Some(id_5.clone()), Some(id_4.clone())),
477 );
478 assert_eq!(
479 mutable_segment.resolve_neighbor_commit_ids(&id_4),
480 (Some(id_3.clone()), None),
481 );
482
483 assert_eq!(
485 mutable_segment.resolve_neighbor_commit_ids(&CommitId::from_hex("033332")),
486 (None, Some(id_5.clone())),
487 );
488 assert_eq!(
489 mutable_segment.resolve_neighbor_commit_ids(&CommitId::from_hex("033334")),
490 (Some(id_5.clone()), Some(id_3.clone())),
491 );
492 assert_eq!(
493 mutable_segment.resolve_neighbor_commit_ids(&CommitId::from_hex("ffffff")),
494 (Some(id_4.clone()), None),
495 );
496
497 let composite_index = CompositeIndex::new(&mutable_segment);
499 assert_eq!(
500 composite_index.resolve_neighbor_commit_ids(&id_0),
501 (None, Some(id_1.clone())),
502 );
503 assert_eq!(
504 composite_index.resolve_neighbor_commit_ids(&id_1),
505 (Some(id_0.clone()), Some(id_5.clone())),
506 );
507 assert_eq!(
508 composite_index.resolve_neighbor_commit_ids(&id_5),
509 (Some(id_1.clone()), Some(id_3.clone())),
510 );
511 assert_eq!(
512 composite_index.resolve_neighbor_commit_ids(&id_3),
513 (Some(id_5.clone()), Some(id_2.clone())),
514 );
515 assert_eq!(
516 composite_index.resolve_neighbor_commit_ids(&id_2),
517 (Some(id_3.clone()), Some(id_4.clone())),
518 );
519 assert_eq!(
520 composite_index.resolve_neighbor_commit_ids(&id_4),
521 (Some(id_2.clone()), None),
522 );
523
524 assert_eq!(
527 composite_index.resolve_neighbor_commit_ids(&CommitId::from_hex("000000")),
528 (None, Some(id_0.clone())),
529 );
530 assert_eq!(
531 composite_index.resolve_neighbor_commit_ids(&CommitId::from_hex("010000")),
532 (Some(id_1.clone()), Some(id_5.clone())),
533 );
534 assert_eq!(
535 composite_index.resolve_neighbor_commit_ids(&CommitId::from_hex("033334")),
536 (Some(id_5.clone()), Some(id_3.clone())),
537 );
538 assert_eq!(
539 composite_index.resolve_neighbor_commit_ids(&CommitId::from_hex("ffffff")),
540 (Some(id_4.clone()), None),
541 );
542 }
543
544 #[test]
545 fn shortest_unique_commit_id_prefix() {
546 let temp_dir = new_temp_dir();
547 let mut new_change_id = change_id_generator();
548 let mut mutable_segment = MutableIndexSegment::full(3, 16);
549
550 let id_0 = CommitId::from_hex("000001");
552 let id_1 = CommitId::from_hex("009999");
553 let id_2 = CommitId::from_hex("055488");
554 mutable_segment.add_commit_data(id_0.clone(), new_change_id(), &[]);
555 mutable_segment.add_commit_data(id_1.clone(), new_change_id(), &[]);
556 mutable_segment.add_commit_data(id_2.clone(), new_change_id(), &[]);
557
558 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
560 mutable_segment = MutableIndexSegment::incremental(initial_file);
561
562 let id_3 = CommitId::from_hex("055444");
563 let id_4 = CommitId::from_hex("055555");
564 let id_5 = CommitId::from_hex("033333");
565 mutable_segment.add_commit_data(id_3.clone(), new_change_id(), &[]);
566 mutable_segment.add_commit_data(id_4.clone(), new_change_id(), &[]);
567 mutable_segment.add_commit_data(id_5.clone(), new_change_id(), &[]);
568
569 let index = mutable_segment.as_composite();
570
571 assert_eq!(index.shortest_unique_commit_id_prefix_len(&id_0), 3);
573 assert_eq!(index.shortest_unique_commit_id_prefix_len(&id_1), 3);
574 assert_eq!(index.shortest_unique_commit_id_prefix_len(&id_2), 5);
575 assert_eq!(index.shortest_unique_commit_id_prefix_len(&id_3), 5);
576 assert_eq!(index.shortest_unique_commit_id_prefix_len(&id_4), 4);
577 assert_eq!(index.shortest_unique_commit_id_prefix_len(&id_5), 2);
578
579 assert_eq!(
581 index.shortest_unique_commit_id_prefix_len(&CommitId::from_hex("000002")),
582 6
583 );
584 assert_eq!(
585 index.shortest_unique_commit_id_prefix_len(&CommitId::from_hex("010000")),
586 2
587 );
588 assert_eq!(
589 index.shortest_unique_commit_id_prefix_len(&CommitId::from_hex("033334")),
590 6
591 );
592 assert_eq!(
593 index.shortest_unique_commit_id_prefix_len(&CommitId::from_hex("ffffff")),
594 1
595 );
596 }
597
598 #[test]
599 fn resolve_change_id_prefix() {
600 let temp_dir = new_temp_dir();
601 let mut new_commit_id = commit_id_generator();
602 let local_positions_vec = |positions: &[u32]| -> SmallLocalPositionsVec {
603 positions.iter().copied().map(LocalPosition).collect()
604 };
605 let index_positions_vec = |positions: &[u32]| -> SmallIndexPositionsVec {
606 positions.iter().copied().map(IndexPosition).collect()
607 };
608
609 let id_0 = ChangeId::from_hex("00000001");
610 let id_1 = ChangeId::from_hex("00999999");
611 let id_2 = ChangeId::from_hex("05548888");
612 let id_3 = ChangeId::from_hex("05544444");
613 let id_4 = ChangeId::from_hex("05555555");
614 let id_5 = ChangeId::from_hex("05555333");
615
616 let mut mutable_segment = MutableIndexSegment::full(16, 4);
618 mutable_segment.add_commit_data(new_commit_id(), id_0.clone(), &[]);
619 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
620 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
621 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
622 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
623 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
624
625 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
627 mutable_segment = MutableIndexSegment::incremental(initial_file.clone());
628
629 mutable_segment.add_commit_data(new_commit_id(), id_3.clone(), &[]);
630 mutable_segment.add_commit_data(new_commit_id(), id_3.clone(), &[]);
631 mutable_segment.add_commit_data(new_commit_id(), id_4.clone(), &[]);
632 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
633 mutable_segment.add_commit_data(new_commit_id(), id_5.clone(), &[]);
634
635 assert_eq!(
637 initial_file.resolve_change_id_prefix(&HexPrefix::new(&id_0.hex()).unwrap()),
638 PrefixResolution::SingleMatch((id_0.clone(), local_positions_vec(&[0])))
639 );
640 assert_eq!(
641 initial_file.resolve_change_id_prefix(&HexPrefix::new(&id_1.hex()).unwrap()),
642 PrefixResolution::SingleMatch((id_1.clone(), local_positions_vec(&[1, 3])))
643 );
644 assert_eq!(
645 initial_file.resolve_change_id_prefix(&HexPrefix::new(&id_2.hex()).unwrap()),
646 PrefixResolution::SingleMatch((id_2.clone(), local_positions_vec(&[2, 4, 5])))
647 );
648
649 assert_eq!(
651 mutable_segment.resolve_change_id_prefix(&HexPrefix::new(&id_1.hex()).unwrap()),
652 PrefixResolution::SingleMatch((id_1.clone(), local_positions_vec(&[3])))
653 );
654 assert_eq!(
655 mutable_segment.resolve_change_id_prefix(&HexPrefix::new(&id_3.hex()).unwrap()),
656 PrefixResolution::SingleMatch((id_3.clone(), local_positions_vec(&[0, 1])))
657 );
658 assert_eq!(
659 mutable_segment.resolve_change_id_prefix(&HexPrefix::new(&id_4.hex()).unwrap()),
660 PrefixResolution::SingleMatch((id_4.clone(), local_positions_vec(&[2])))
661 );
662 assert_eq!(
663 mutable_segment.resolve_change_id_prefix(&HexPrefix::new(&id_5.hex()).unwrap()),
664 PrefixResolution::SingleMatch((id_5.clone(), local_positions_vec(&[4])))
665 );
666
667 assert_eq!(
669 initial_file.resolve_change_id_prefix(&HexPrefix::new("0555").unwrap()),
670 PrefixResolution::NoMatch
671 );
672 assert_eq!(
673 mutable_segment.resolve_change_id_prefix(&HexPrefix::new("000").unwrap()),
674 PrefixResolution::NoMatch
675 );
676
677 assert_eq!(
679 initial_file.resolve_change_id_prefix(&HexPrefix::new("0554").unwrap()),
680 PrefixResolution::SingleMatch((id_2.clone(), local_positions_vec(&[2, 4, 5])))
681 );
682 assert_eq!(
683 mutable_segment.resolve_change_id_prefix(&HexPrefix::new("0554").unwrap()),
684 PrefixResolution::SingleMatch((id_3.clone(), local_positions_vec(&[0, 1])))
685 );
686
687 assert_eq!(
689 initial_file.resolve_change_id_prefix(&HexPrefix::new("00").unwrap()),
690 PrefixResolution::AmbiguousMatch
691 );
692 assert_eq!(
693 mutable_segment.resolve_change_id_prefix(&HexPrefix::new("05555").unwrap()),
694 PrefixResolution::AmbiguousMatch
695 );
696
697 let index = mutable_segment.as_composite();
698
699 assert_eq!(
701 index.resolve_change_id_prefix(&HexPrefix::new(&id_0.hex()).unwrap()),
702 PrefixResolution::SingleMatch((id_0.clone(), index_positions_vec(&[0])))
703 );
704 assert_eq!(
705 index.resolve_change_id_prefix(&HexPrefix::new(&id_1.hex()).unwrap()),
706 PrefixResolution::SingleMatch((id_1.clone(), index_positions_vec(&[1, 3, 9])))
707 );
708 assert_eq!(
709 index.resolve_change_id_prefix(&HexPrefix::new(&id_2.hex()).unwrap()),
710 PrefixResolution::SingleMatch((id_2.clone(), index_positions_vec(&[2, 4, 5])))
711 );
712 assert_eq!(
713 index.resolve_change_id_prefix(&HexPrefix::new(&id_3.hex()).unwrap()),
714 PrefixResolution::SingleMatch((id_3.clone(), index_positions_vec(&[6, 7])))
715 );
716 assert_eq!(
717 index.resolve_change_id_prefix(&HexPrefix::new(&id_4.hex()).unwrap()),
718 PrefixResolution::SingleMatch((id_4.clone(), index_positions_vec(&[8])))
719 );
720 assert_eq!(
721 index.resolve_change_id_prefix(&HexPrefix::new(&id_5.hex()).unwrap()),
722 PrefixResolution::SingleMatch((id_5.clone(), index_positions_vec(&[10])))
723 );
724
725 assert_eq!(
727 index.resolve_change_id_prefix(&HexPrefix::new("ffffffff").unwrap()),
728 PrefixResolution::NoMatch
729 );
730 assert_eq!(
731 index.resolve_change_id_prefix(&HexPrefix::new("00000002").unwrap()),
732 PrefixResolution::NoMatch
733 );
734
735 assert_eq!(
737 index.resolve_change_id_prefix(&HexPrefix::new("000").unwrap()),
738 PrefixResolution::SingleMatch((id_0.clone(), index_positions_vec(&[0])))
739 );
740 assert_eq!(
741 index.resolve_change_id_prefix(&HexPrefix::new("055553").unwrap()),
742 PrefixResolution::SingleMatch((id_5.clone(), index_positions_vec(&[10])))
743 );
744
745 assert_eq!(
747 index.resolve_change_id_prefix(&HexPrefix::new("009").unwrap()),
748 PrefixResolution::SingleMatch((id_1.clone(), index_positions_vec(&[1, 3, 9])))
749 );
750
751 assert_eq!(
753 index.resolve_change_id_prefix(&HexPrefix::new("00").unwrap()),
754 PrefixResolution::AmbiguousMatch
755 );
756 assert_eq!(
757 index.resolve_change_id_prefix(&HexPrefix::new("05555").unwrap()),
758 PrefixResolution::AmbiguousMatch
759 );
760
761 assert_eq!(
763 index.resolve_change_id_prefix(&HexPrefix::new("0554").unwrap()),
764 PrefixResolution::AmbiguousMatch
765 );
766 }
767
768 #[test]
769 fn neighbor_change_ids() {
770 let temp_dir = new_temp_dir();
771 let mut new_commit_id = commit_id_generator();
772
773 let id_0 = ChangeId::from_hex("00000001");
774 let id_1 = ChangeId::from_hex("00999999");
775 let id_2 = ChangeId::from_hex("05548888");
776 let id_3 = ChangeId::from_hex("05544444");
777 let id_4 = ChangeId::from_hex("05555555");
778 let id_5 = ChangeId::from_hex("05555333");
779
780 let mut mutable_segment = MutableIndexSegment::full(16, 4);
782 mutable_segment.add_commit_data(new_commit_id(), id_0.clone(), &[]);
783 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
784 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
785 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
786 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
787 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
788
789 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
791 mutable_segment = MutableIndexSegment::incremental(initial_file.clone());
792
793 mutable_segment.add_commit_data(new_commit_id(), id_3.clone(), &[]);
794 mutable_segment.add_commit_data(new_commit_id(), id_3.clone(), &[]);
795 mutable_segment.add_commit_data(new_commit_id(), id_4.clone(), &[]);
796 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
797 mutable_segment.add_commit_data(new_commit_id(), id_5.clone(), &[]);
798
799 assert_eq!(
801 initial_file.resolve_neighbor_change_ids(&id_0),
802 (None, Some(id_1.clone())),
803 );
804 assert_eq!(
805 initial_file.resolve_neighbor_change_ids(&id_1),
806 (Some(id_0.clone()), Some(id_2.clone())),
807 );
808 assert_eq!(
809 initial_file.resolve_neighbor_change_ids(&id_2),
810 (Some(id_1.clone()), None),
811 );
812
813 assert_eq!(
815 initial_file.resolve_neighbor_change_ids(&ChangeId::from_hex("00000000")),
816 (None, Some(id_0.clone())),
817 );
818 assert_eq!(
819 initial_file.resolve_neighbor_change_ids(&ChangeId::from_hex("00000002")),
820 (Some(id_0.clone()), Some(id_1.clone())),
821 );
822 assert_eq!(
823 initial_file.resolve_neighbor_change_ids(&ChangeId::from_hex("ffffffff")),
824 (Some(id_2.clone()), None),
825 );
826
827 assert_eq!(
830 mutable_segment.resolve_neighbor_change_ids(&id_1),
831 (None, Some(id_3.clone())),
832 );
833 assert_eq!(
834 mutable_segment.resolve_neighbor_change_ids(&id_3),
835 (Some(id_1.clone()), Some(id_5.clone())),
836 );
837 assert_eq!(
838 mutable_segment.resolve_neighbor_change_ids(&id_5),
839 (Some(id_3.clone()), Some(id_4.clone())),
840 );
841 assert_eq!(
842 mutable_segment.resolve_neighbor_change_ids(&id_4),
843 (Some(id_5.clone()), None),
844 );
845
846 assert_eq!(
849 mutable_segment.resolve_neighbor_change_ids(&ChangeId::from_hex("00999998")),
850 (None, Some(id_1.clone())),
851 );
852 assert_eq!(
853 mutable_segment.resolve_neighbor_change_ids(&ChangeId::from_hex("01000000")),
854 (Some(id_1.clone()), Some(id_3.clone())),
855 );
856 assert_eq!(
857 mutable_segment.resolve_neighbor_change_ids(&ChangeId::from_hex("05555332")),
858 (Some(id_3.clone()), Some(id_5.clone())),
859 );
860 assert_eq!(
861 mutable_segment.resolve_neighbor_change_ids(&ChangeId::from_hex("ffffffff")),
862 (Some(id_4.clone()), None),
863 );
864
865 let index = mutable_segment.as_composite();
866
867 assert_eq!(
870 index.resolve_neighbor_change_ids(&id_0),
871 (None, Some(id_1.clone())),
872 );
873 assert_eq!(
874 index.resolve_neighbor_change_ids(&id_1),
875 (Some(id_0.clone()), Some(id_3.clone())),
876 );
877 assert_eq!(
878 index.resolve_neighbor_change_ids(&id_3),
879 (Some(id_1.clone()), Some(id_2.clone())),
880 );
881 assert_eq!(
882 index.resolve_neighbor_change_ids(&id_2),
883 (Some(id_3.clone()), Some(id_5.clone())),
884 );
885 assert_eq!(
886 index.resolve_neighbor_change_ids(&id_5),
887 (Some(id_2.clone()), Some(id_4.clone())),
888 );
889 assert_eq!(
890 index.resolve_neighbor_change_ids(&id_4),
891 (Some(id_5.clone()), None),
892 );
893
894 assert_eq!(
897 index.resolve_neighbor_change_ids(&ChangeId::from_hex("00000000")),
898 (None, Some(id_0.clone())),
899 );
900 assert_eq!(
901 index.resolve_neighbor_change_ids(&ChangeId::from_hex("01000000")),
902 (Some(id_1.clone()), Some(id_3.clone())),
903 );
904 assert_eq!(
905 index.resolve_neighbor_change_ids(&ChangeId::from_hex("05544555")),
906 (Some(id_3.clone()), Some(id_2.clone())),
907 );
908 assert_eq!(
909 index.resolve_neighbor_change_ids(&ChangeId::from_hex("ffffffff")),
910 (Some(id_4.clone()), None),
911 );
912 }
913
914 #[test]
915 fn shortest_unique_change_id_prefix() {
916 let temp_dir = new_temp_dir();
917 let mut new_commit_id = commit_id_generator();
918
919 let id_0 = ChangeId::from_hex("00000001");
920 let id_1 = ChangeId::from_hex("00999999");
921 let id_2 = ChangeId::from_hex("05548888");
922 let id_3 = ChangeId::from_hex("05544444");
923 let id_4 = ChangeId::from_hex("05555555");
924 let id_5 = ChangeId::from_hex("05555333");
925
926 let mut mutable_segment = MutableIndexSegment::full(16, 4);
928 mutable_segment.add_commit_data(new_commit_id(), id_0.clone(), &[]);
929 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
930 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
931 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
932 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
933 mutable_segment.add_commit_data(new_commit_id(), id_2.clone(), &[]);
934
935 let initial_file = mutable_segment.save_in(temp_dir.path()).unwrap();
937 mutable_segment = MutableIndexSegment::incremental(initial_file.clone());
938
939 mutable_segment.add_commit_data(new_commit_id(), id_3.clone(), &[]);
940 mutable_segment.add_commit_data(new_commit_id(), id_3.clone(), &[]);
941 mutable_segment.add_commit_data(new_commit_id(), id_4.clone(), &[]);
942 mutable_segment.add_commit_data(new_commit_id(), id_1.clone(), &[]);
943 mutable_segment.add_commit_data(new_commit_id(), id_5.clone(), &[]);
944
945 let index = mutable_segment.as_composite();
946
947 assert_eq!(index.shortest_unique_change_id_prefix_len(&id_0), 3);
949 assert_eq!(index.shortest_unique_change_id_prefix_len(&id_1), 3);
950 assert_eq!(index.shortest_unique_change_id_prefix_len(&id_2), 5);
951 assert_eq!(index.shortest_unique_change_id_prefix_len(&id_3), 5);
952 assert_eq!(index.shortest_unique_change_id_prefix_len(&id_4), 6);
953 assert_eq!(index.shortest_unique_change_id_prefix_len(&id_5), 6);
954
955 assert_eq!(
957 index.shortest_unique_change_id_prefix_len(&ChangeId::from_hex("00000002")),
958 8
959 );
960 assert_eq!(
961 index.shortest_unique_change_id_prefix_len(&ChangeId::from_hex("01000000")),
962 2
963 );
964 assert_eq!(
965 index.shortest_unique_change_id_prefix_len(&ChangeId::from_hex("05555344")),
966 7
967 );
968 assert_eq!(
969 index.shortest_unique_change_id_prefix_len(&ChangeId::from_hex("ffffffff")),
970 1
971 );
972 }
973
974 #[test]
975 fn test_is_ancestor() {
976 let mut new_change_id = change_id_generator();
977 let mut index = DefaultMutableIndex::full(3, 16);
978 let id_0 = CommitId::from_hex("000000");
986 let id_1 = CommitId::from_hex("111111");
987 let id_2 = CommitId::from_hex("222222");
988 let id_3 = CommitId::from_hex("333333");
989 let id_4 = CommitId::from_hex("444444");
990 let id_5 = CommitId::from_hex("555555");
991 index.add_commit_data(id_0.clone(), new_change_id(), &[]);
992 index.add_commit_data(id_1.clone(), new_change_id(), &[id_0.clone()]);
993 index.add_commit_data(id_2.clone(), new_change_id(), &[id_0.clone()]);
994 index.add_commit_data(id_3.clone(), new_change_id(), &[id_2.clone()]);
995 index.add_commit_data(id_4.clone(), new_change_id(), &[id_1.clone()]);
996 index.add_commit_data(id_5.clone(), new_change_id(), &[id_4.clone(), id_2.clone()]);
997
998 assert!(index.is_ancestor(&id_0, &id_0));
999 assert!(index.is_ancestor(&id_0, &id_1));
1000 assert!(index.is_ancestor(&id_2, &id_3));
1001 assert!(index.is_ancestor(&id_2, &id_5));
1002 assert!(index.is_ancestor(&id_1, &id_5));
1003 assert!(index.is_ancestor(&id_0, &id_5));
1004 assert!(!index.is_ancestor(&id_1, &id_0));
1005 assert!(!index.is_ancestor(&id_5, &id_3));
1006 assert!(!index.is_ancestor(&id_3, &id_5));
1007 assert!(!index.is_ancestor(&id_2, &id_4));
1008 assert!(!index.is_ancestor(&id_4, &id_2));
1009 }
1010
1011 #[test]
1012 fn test_common_ancestors() {
1013 let mut new_change_id = change_id_generator();
1014 let mut index = DefaultMutableIndex::full(3, 16);
1015 let id_0 = CommitId::from_hex("000000");
1024 let id_1 = CommitId::from_hex("111111");
1025 let id_2 = CommitId::from_hex("222222");
1026 let id_3 = CommitId::from_hex("333333");
1027 let id_4 = CommitId::from_hex("444444");
1028 let id_5 = CommitId::from_hex("555555");
1029 let id_6 = CommitId::from_hex("666666");
1030 index.add_commit_data(id_0.clone(), new_change_id(), &[]);
1031 index.add_commit_data(id_1.clone(), new_change_id(), &[id_0.clone()]);
1032 index.add_commit_data(id_2.clone(), new_change_id(), &[id_0.clone()]);
1033 index.add_commit_data(id_3.clone(), new_change_id(), &[id_0.clone()]);
1034 index.add_commit_data(id_4.clone(), new_change_id(), &[id_1.clone()]);
1035 index.add_commit_data(id_5.clone(), new_change_id(), &[id_4.clone(), id_2.clone()]);
1036 index.add_commit_data(id_6.clone(), new_change_id(), &[id_4.clone()]);
1037
1038 assert_eq!(
1039 index.common_ancestors(&[id_0.clone()], &[id_0.clone()]),
1040 vec![id_0.clone()]
1041 );
1042 assert_eq!(
1043 index.common_ancestors(&[id_5.clone()], &[id_5.clone()]),
1044 vec![id_5.clone()]
1045 );
1046 assert_eq!(
1047 index.common_ancestors(&[id_1.clone()], &[id_2.clone()]),
1048 vec![id_0.clone()]
1049 );
1050 assert_eq!(
1051 index.common_ancestors(&[id_2.clone()], &[id_1.clone()]),
1052 vec![id_0.clone()]
1053 );
1054 assert_eq!(
1055 index.common_ancestors(&[id_1.clone()], &[id_4.clone()]),
1056 vec![id_1.clone()]
1057 );
1058 assert_eq!(
1059 index.common_ancestors(&[id_4.clone()], &[id_1.clone()]),
1060 vec![id_1.clone()]
1061 );
1062 assert_eq!(
1063 index.common_ancestors(&[id_3.clone()], &[id_5.clone()]),
1064 vec![id_0.clone()]
1065 );
1066 assert_eq!(
1067 index.common_ancestors(&[id_5.clone()], &[id_3.clone()]),
1068 vec![id_0.clone()]
1069 );
1070 assert_eq!(
1071 index.common_ancestors(&[id_2.clone()], &[id_6.clone()]),
1072 vec![id_0.clone()]
1073 );
1074
1075 assert_eq!(
1077 index.common_ancestors(&[id_0.clone(), id_1.clone()], &[id_0.clone()]),
1078 vec![id_0.clone()]
1079 );
1080 assert_eq!(
1081 index.common_ancestors(&[id_0.clone(), id_1.clone()], &[id_1.clone()]),
1082 vec![id_1.clone()]
1083 );
1084 assert_eq!(
1085 index.common_ancestors(&[id_1.clone(), id_2.clone()], &[id_1.clone()]),
1086 vec![id_1.clone()]
1087 );
1088 assert_eq!(
1089 index.common_ancestors(&[id_1.clone(), id_2.clone()], &[id_4]),
1090 vec![id_1.clone()]
1091 );
1092 assert_eq!(
1093 index.common_ancestors(&[id_5.clone(), id_6.clone()], &[id_2.clone()]),
1094 &[id_2.clone()]
1095 );
1096 assert_eq!(
1099 index.common_ancestors(&[id_1.clone(), id_2.clone()], &[id_5]),
1100 vec![id_2.clone(), id_1.clone()]
1101 );
1102 assert_eq!(index.common_ancestors(&[id_1, id_2], &[id_3]), vec![id_0]);
1103 }
1104
1105 #[test]
1106 fn test_common_ancestors_criss_cross() {
1107 let mut new_change_id = change_id_generator();
1108 let mut index = DefaultMutableIndex::full(3, 16);
1109 let id_0 = CommitId::from_hex("000000");
1115 let id_1 = CommitId::from_hex("111111");
1116 let id_2 = CommitId::from_hex("222222");
1117 let id_3 = CommitId::from_hex("333333");
1118 let id_4 = CommitId::from_hex("444444");
1119 index.add_commit_data(id_0.clone(), new_change_id(), &[]);
1120 index.add_commit_data(id_1.clone(), new_change_id(), &[id_0.clone()]);
1121 index.add_commit_data(id_2.clone(), new_change_id(), &[id_0]);
1122 index.add_commit_data(id_3.clone(), new_change_id(), &[id_1.clone(), id_2.clone()]);
1123 index.add_commit_data(id_4.clone(), new_change_id(), &[id_1.clone(), id_2.clone()]);
1124
1125 let mut common_ancestors = index.common_ancestors(&[id_3], &[id_4]);
1126 common_ancestors.sort();
1127 assert_eq!(common_ancestors, vec![id_1, id_2]);
1128 }
1129
1130 #[test]
1131 fn test_common_ancestors_merge_with_ancestor() {
1132 let mut new_change_id = change_id_generator();
1133 let mut index = DefaultMutableIndex::full(3, 16);
1134 let id_0 = CommitId::from_hex("000000");
1140 let id_1 = CommitId::from_hex("111111");
1141 let id_2 = CommitId::from_hex("222222");
1142 let id_3 = CommitId::from_hex("333333");
1143 let id_4 = CommitId::from_hex("444444");
1144 let id_5 = CommitId::from_hex("555555");
1145 index.add_commit_data(id_0.clone(), new_change_id(), &[]);
1146 index.add_commit_data(id_1, new_change_id(), &[id_0.clone()]);
1147 index.add_commit_data(id_2.clone(), new_change_id(), &[id_0.clone()]);
1148 index.add_commit_data(id_3, new_change_id(), &[id_0.clone()]);
1149 index.add_commit_data(id_4.clone(), new_change_id(), &[id_0.clone(), id_2.clone()]);
1150 index.add_commit_data(id_5.clone(), new_change_id(), &[id_0, id_2.clone()]);
1151
1152 let mut common_ancestors = index.common_ancestors(&[id_4], &[id_5]);
1153 common_ancestors.sort();
1154 assert_eq!(common_ancestors, vec![id_2]);
1155 }
1156
1157 #[test]
1158 fn test_heads() {
1159 let mut new_change_id = change_id_generator();
1160 let mut index = DefaultMutableIndex::full(3, 16);
1161 let id_0 = CommitId::from_hex("000000");
1169 let id_1 = CommitId::from_hex("111111");
1170 let id_2 = CommitId::from_hex("222222");
1171 let id_3 = CommitId::from_hex("333333");
1172 let id_4 = CommitId::from_hex("444444");
1173 let id_5 = CommitId::from_hex("555555");
1174 index.add_commit_data(id_0.clone(), new_change_id(), &[]);
1175 index.add_commit_data(id_1.clone(), new_change_id(), &[id_0.clone()]);
1176 index.add_commit_data(id_2.clone(), new_change_id(), &[id_0.clone()]);
1177 index.add_commit_data(id_3.clone(), new_change_id(), &[id_2.clone()]);
1178 index.add_commit_data(id_4.clone(), new_change_id(), &[id_1.clone()]);
1179 index.add_commit_data(id_5.clone(), new_change_id(), &[id_4.clone(), id_2.clone()]);
1180
1181 assert!(index.heads(&mut [].iter()).unwrap().is_empty());
1183 assert_eq!(
1185 index.heads(&mut [id_4.clone()].iter()).unwrap(),
1186 vec![id_4.clone()]
1187 );
1188 assert_eq!(
1190 index.heads(&mut [id_4.clone(), id_1].iter()).unwrap(),
1191 vec![id_4.clone()]
1192 );
1193 assert_eq!(
1195 index.heads(&mut [id_4.clone(), id_0].iter()).unwrap(),
1196 vec![id_4.clone()]
1197 );
1198 assert_eq!(
1200 index
1201 .heads(&mut [id_3.clone(), id_4.clone()].iter())
1202 .unwrap(),
1203 vec![id_4.clone(), id_3.clone()]
1204 );
1205 assert_eq!(
1207 index
1208 .heads(&mut [id_4.clone(), id_3.clone(), id_4.clone()].iter())
1209 .unwrap(),
1210 vec![id_4.clone(), id_3.clone()]
1211 );
1212 assert_eq!(
1214 index.heads(&mut [id_5.clone(), id_2].iter()).unwrap(),
1215 vec![id_5.clone()]
1216 );
1217 assert_eq!(
1219 index
1220 .heads(&mut [id_5.clone(), id_3.clone()].iter())
1221 .unwrap(),
1222 vec![id_5.clone(), id_3.clone()]
1223 );
1224
1225 assert_eq!(
1226 index.all_heads_for_gc().unwrap().collect_vec(),
1227 vec![id_3.clone(), id_5.clone()]
1228 );
1229 }
1230}