Skip to content

Commit 8698247

Browse files
authored
perf: implement slice access to individual data (#292)
BREAKING CHANGE: changes return value of IndividualTable::parents and ::location
1 parent 5ecf922 commit 8698247

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

src/_macros.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ macro_rules! unsafe_tsk_ragged_column_access {
7070
}
7171
}};
7272

73-
($i: expr, $lo: expr, $hi: expr, $array: expr, $offset_array: expr, $offset_array_len: expr, $output_id_type: expr) => {{
73+
($i: expr, $lo: expr, $hi: expr, $array: expr, $offset_array: expr, $offset_array_len: expr, $output_id_type: ty) => {{
7474
let i = $crate::SizeType::try_from($i)?;
7575
if $i < $lo || i >= $hi {
7676
Err(TskitError::IndexError {})
@@ -86,11 +86,12 @@ macro_rules! unsafe_tsk_ragged_column_access {
8686
if start == stop {
8787
Ok(None)
8888
} else {
89-
let mut buffer = vec![];
90-
for i in start..stop {
91-
buffer.push($output_id_type(unsafe { *$array.offset(i as isize) }));
92-
}
93-
Ok(Some(buffer))
89+
Ok(Some(unsafe {
90+
std::slice::from_raw_parts(
91+
$array.offset(start as isize) as *const $output_id_type,
92+
stop as usize - start as usize,
93+
)
94+
}))
9495
}
9596
}
9697
}};

src/individual_table.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ fn make_individual_table_row(table: &IndividualTable, pos: tsk_id_t) -> Option<I
6161
let rv = IndividualTableRow {
6262
id: pos.into(),
6363
flags: table.flags(pos).unwrap(),
64-
location: table.location(pos).unwrap(),
65-
parents: table.parents(pos).unwrap(),
64+
location: table.location(pos).unwrap().map(|s| s.to_vec()),
65+
parents: table.parents(pos).unwrap().map(|s| s.to_vec()),
6666
metadata: table_row_decode_metadata!(table_ref, pos),
6767
};
6868
Some(rv)
@@ -131,7 +131,7 @@ impl<'a> IndividualTable<'a> {
131131
pub fn location<I: Into<IndividualId> + Copy>(
132132
&self,
133133
row: I,
134-
) -> Result<Option<Vec<Location>>, TskitError> {
134+
) -> Result<Option<&[Location]>, TskitError> {
135135
unsafe_tsk_ragged_column_access!(
136136
row.into().0,
137137
0,
@@ -151,7 +151,7 @@ impl<'a> IndividualTable<'a> {
151151
pub fn parents<I: Into<IndividualId> + Copy>(
152152
&self,
153153
row: I,
154-
) -> Result<Option<Vec<IndividualId>>, TskitError> {
154+
) -> Result<Option<&[IndividualId]>, TskitError> {
155155
unsafe_tsk_ragged_column_access!(
156156
row.into().0,
157157
0,

src/table_collection.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,15 +1567,40 @@ mod test_adding_individual {
15671567
);
15681568

15691569
// Empty slices are a thing, causing None to be in the rows.
1570-
1571-
let mut tables = crate::test_fixtures::make_empty_table_collection(10.);
15721570
let row_id = tables
15731571
.add_individual(0, &[] as &[f64], &[] as &[IndividualId])
15741572
.unwrap();
15751573
let row = tables.individuals().row(row_id).unwrap();
1576-
assert_eq!(row.id, IndividualId::from(0));
1574+
assert_eq!(row.id, IndividualId::from(1));
15771575
assert!(row.location.is_none());
15781576
assert!(row.parents.is_none());
1577+
let row_id = tables
1578+
.add_individual(0, &[0.2, 0.4, 0.6], &[1, 2, 3, 4])
1579+
.unwrap();
1580+
assert_eq!(row_id, 2);
1581+
assert_eq!(
1582+
tables.individuals().location(row_id).unwrap(),
1583+
Some(
1584+
[
1585+
crate::Location::from(0.2),
1586+
crate::Location::from(0.4),
1587+
crate::Location::from(0.6)
1588+
]
1589+
.as_slice()
1590+
)
1591+
);
1592+
assert_eq!(
1593+
tables.individuals().parents(row_id).unwrap(),
1594+
Some(
1595+
[
1596+
crate::IndividualId::from(1),
1597+
crate::IndividualId::from(2),
1598+
crate::IndividualId::from(3),
1599+
crate::IndividualId::from(4)
1600+
]
1601+
.as_slice()
1602+
)
1603+
);
15791604
}
15801605

15811606
#[test]

0 commit comments

Comments
 (0)