@@ -5,6 +5,7 @@ use crate::metadata::*;
5
5
use crate :: types:: Bookmark ;
6
6
use crate :: EdgeTable ;
7
7
use crate :: IndividualTable ;
8
+ use crate :: IndividualTableSortOptions ;
8
9
use crate :: Location ;
9
10
use crate :: MigrationTable ;
10
11
use crate :: MutationTable ;
@@ -597,6 +598,12 @@ impl TableCollection {
597
598
/// Sort the tables.
598
599
/// The [``bookmark``](crate::types::Bookmark) can
599
600
/// be used to affect where sorting starts from for each table.
601
+ ///
602
+ /// # Warning
603
+ ///
604
+ /// As of `0.7.0`, this function does not sort the individual table!
605
+ /// See
606
+ /// [``topological_sort_individuals``](crate::TableCollection::topological_sort_individuals).
600
607
pub fn sort ( & mut self , start : & Bookmark , options : TableSortOptions ) -> TskReturnValue {
601
608
let rv = unsafe {
602
609
ll_bindings:: tsk_table_collection_sort (
@@ -611,11 +618,73 @@ impl TableCollection {
611
618
612
619
/// Fully sort all functions.
613
620
/// Implemented via a call to [``sort``](crate::TableCollection::sort).
621
+ ///
622
+ /// # Warning
623
+ ///
624
+ /// As of `0.7.0`, this function does not sort the individual table!
625
+ /// See
626
+ /// [``topological_sort_individuals``](crate::TableCollection::topological_sort_individuals).
614
627
pub fn full_sort ( & mut self , options : TableSortOptions ) -> TskReturnValue {
615
628
let b = Bookmark :: new ( ) ;
616
629
self . sort ( & b, options)
617
630
}
618
631
632
+ /// Sorts the individual table in place, so that parents come before children,
633
+ /// and the parent column is remapped as required. Node references to individuals
634
+ /// are also updated.
635
+ ///
636
+ /// This function is needed because neither [``sort``](crate::TableCollection::sort) nor
637
+ /// [``full_sort``](crate::TableCollection::full_sort) sorts
638
+ /// the individual table!
639
+ ///
640
+ /// # Examples
641
+ ///
642
+ /// ```
643
+ /// // Parent comes AFTER the child
644
+ /// let mut tables = tskit::TableCollection::new(1.0).unwrap();
645
+ /// let i0 = tables.add_individual::<i32, f64>(0,&[],&[1]).unwrap();
646
+ /// assert_eq!(i0, 0);
647
+ /// let i1 = tables.add_individual::<i32, f64>(0,&[],&[]).unwrap();
648
+ /// assert_eq!(i1, 1);
649
+ /// let n0 = tables.add_node(0, 0.0, -1, i1).unwrap();
650
+ /// assert_eq!(n0, 0);
651
+ /// let n1 = tables.add_node(0, 1.0, -1, i0).unwrap();
652
+ /// assert_eq!(n1, 1);
653
+ ///
654
+ /// // Testing for valid individual order will Err:
655
+ /// match tables.check_integrity(tskit::TableIntegrityCheckFlags::CHECK_INDIVIDUAL_ORDERING) {
656
+ /// Ok(_) => panic!("expected Err"),
657
+ /// Err(_) => (),
658
+ /// };
659
+ ///
660
+ /// // The standard sort doesn't fix the Err...:
661
+ /// tables.full_sort(tskit::TableSortOptions::default()).unwrap();
662
+ /// match tables.check_integrity(tskit::TableIntegrityCheckFlags::CHECK_INDIVIDUAL_ORDERING) {
663
+ /// Ok(_) => panic!("expected Err"),
664
+ /// Err(_) => (),
665
+ /// };
666
+ ///
667
+ /// // ... so we need to intentionally sort the individuals.
668
+ /// let _ = tables.topological_sort_individuals(tskit::IndividualTableSortOptions::default()).unwrap();
669
+ /// tables.check_integrity(tskit::TableIntegrityCheckFlags::CHECK_INDIVIDUAL_ORDERING).unwrap();
670
+ /// ```
671
+ ///
672
+ /// # Errors
673
+ ///
674
+ /// Will return an error code if the underlying `C` function returns an error.
675
+ pub fn topological_sort_individuals (
676
+ & mut self ,
677
+ options : IndividualTableSortOptions ,
678
+ ) -> TskReturnValue {
679
+ let rv = unsafe {
680
+ ll_bindings:: tsk_table_collection_individual_topological_sort (
681
+ self . as_mut_ptr ( ) ,
682
+ options. bits ( ) ,
683
+ )
684
+ } ;
685
+ handle_tsk_return_value ! ( rv)
686
+ }
687
+
619
688
/// Dump the table collection to file.
620
689
///
621
690
pub fn dump ( & self , filename : & str , options : TableOutputOptions ) -> TskReturnValue {
0 commit comments