Skip to content

Commit 77bdf75

Browse files
authored
refactor: low level tables/tree sequences (#622)
* tree sequences prefer newtypes over raw C types * improved mechanics for tables -> tree seq ownership transfer
1 parent a210ca9 commit 77bdf75

File tree

5 files changed

+28
-28
lines changed

5 files changed

+28
-28
lines changed

src/sys/table_collection.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,8 @@ impl TableCollection {
105105
// SAFETY: self pointer is not null
106106
unsafe { &mut (*self.as_mut_ptr()).sites }
107107
}
108+
109+
pub fn into_raw(self) -> *mut tsk_table_collection_t {
110+
unsafe { self.0.into_raw() }
111+
}
108112
}

src/sys/tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ impl<'treeseq> LLTree<'treeseq> {
2525
let code = unsafe {
2626
super::bindings::tsk_tree_set_tracked_samples(
2727
inner.as_mut(),
28-
treeseq.num_samples(),
28+
treeseq.num_samples().into(),
2929
(inner.as_mut()).samples,
3030
)
3131
};

src/sys/treeseq.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ pub struct TreeSequence(TskBox<bindings::tsk_treeseq_t>);
1111

1212
impl TreeSequence {
1313
pub fn new(
14-
tables: *mut bindings::tsk_table_collection_t,
14+
tables: super::TableCollection,
1515
flags: super::flags::TreeSequenceFlags,
1616
) -> Result<Self, TskitError> {
17+
let tables = tables.into_raw();
1718
let inner = TskBox::new(|t: *mut bindings::tsk_treeseq_t| unsafe {
1819
tsk_treeseq_init(t, tables, flags.bits() | bindings::TSK_TAKE_OWNERSHIP)
1920
})?;
@@ -30,9 +31,9 @@ impl TreeSequence {
3031

3132
pub fn simplify(
3233
&self,
33-
samples: &[bindings::tsk_id_t],
34+
samples: &[super::newtypes::NodeId],
3435
options: super::flags::SimplificationOptions,
35-
idmap: *mut bindings::tsk_id_t,
36+
idmap: Option<&mut [super::newtypes::NodeId]>,
3637
) -> Result<Self, TskitError> {
3738
// The output is an UNINITIALIZED treeseq,
3839
// else we leak memory.
@@ -42,11 +43,15 @@ impl TreeSequence {
4243
let rv = unsafe {
4344
bindings::tsk_treeseq_simplify(
4445
self.as_ref(),
45-
samples.as_ptr(),
46-
samples.len() as bindings::tsk_size_t,
46+
// The cast is safe/sound b/c NodeId is repr(transparent)
47+
samples.as_ptr().cast::<_>(),
48+
samples.len().try_into().unwrap(),
4749
options.bits(),
4850
ts.as_mut_ptr(),
49-
idmap,
51+
match idmap {
52+
Some(s) => s.as_mut_ptr().cast::<_>(),
53+
None => std::ptr::null_mut(),
54+
},
5055
)
5156
};
5257
if rv < 0 {
@@ -72,9 +77,9 @@ impl TreeSequence {
7277
}
7378
}
7479

75-
pub fn num_trees(&self) -> bindings::tsk_size_t {
80+
pub fn num_trees(&self) -> super::newtypes::SizeType {
7681
// SAFETY: self pointer is not null
77-
unsafe { bindings::tsk_treeseq_get_num_trees(self.as_ref()) }
82+
unsafe { bindings::tsk_treeseq_get_num_trees(self.as_ref()) }.into()
7883
}
7984

8085
pub fn num_nodes_raw(&self) -> bindings::tsk_size_t {
@@ -95,7 +100,7 @@ impl TreeSequence {
95100
}
96101
}
97102

98-
pub fn num_samples(&self) -> bindings::tsk_size_t {
99-
unsafe { bindings::tsk_treeseq_get_num_samples(self.as_ref()) }
103+
pub fn num_samples(&self) -> super::newtypes::SizeType {
104+
unsafe { bindings::tsk_treeseq_get_num_samples(self.as_ref()) }.into()
100105
}
101106
}

src/table_collection.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,8 @@ impl TableCollection {
109109
})
110110
}
111111

112-
pub(crate) fn into_raw(self) -> Result<*mut ll_bindings::tsk_table_collection_t, TskitError> {
113-
let mut tables = self;
114-
let mut temp = crate::sys::TableCollection::new(1.)?;
115-
std::mem::swap(&mut temp, &mut tables.inner);
116-
let ptr = temp.as_mut_ptr();
117-
std::mem::forget(temp);
118-
handle_tsk_return_value!(0, ptr)
112+
pub(crate) fn into_inner(self) -> crate::sys::TableCollection {
113+
self.inner
119114
}
120115

121116
/// Load a table collection from a file.

src/trees/treeseq.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::TableOutputOptions;
99
use crate::TreeFlags;
1010
use crate::TreeSequenceFlags;
1111
use crate::TskReturnValue;
12-
use ll_bindings::tsk_id_t;
1312
use sys::bindings as ll_bindings;
1413

1514
use super::Tree;
@@ -113,7 +112,7 @@ impl TreeSequence {
113112
tables: TableCollection,
114113
flags: F,
115114
) -> Result<Self, TskitError> {
116-
let raw_tables_ptr = tables.into_raw()?;
115+
let raw_tables_ptr = tables.into_inner();
117116
let mut inner = sys::TreeSequence::new(raw_tables_ptr, flags.into())?;
118117
let views = crate::table_views::TableViews::new_from_tree_sequence(inner.as_mut())?;
119118
Ok(Self { inner, views })
@@ -302,7 +301,7 @@ impl TreeSequence {
302301

303302
/// Get the number of trees.
304303
pub fn num_trees(&self) -> SizeType {
305-
self.inner.num_trees().into()
304+
self.inner.num_trees()
306305
}
307306

308307
/// Calculate the average Kendall-Colijn (`K-C`) distance between
@@ -322,7 +321,7 @@ impl TreeSequence {
322321

323322
// FIXME: document
324323
pub fn num_samples(&self) -> SizeType {
325-
self.inner.num_samples().into()
324+
self.inner.num_samples()
326325
}
327326

328327
/// Simplify tables and return a new tree sequence.
@@ -348,15 +347,12 @@ impl TreeSequence {
348347
if idmap {
349348
output_node_map.resize(usize::try_from(self.nodes().num_rows())?, NodeId::NULL);
350349
}
351-
let llsamples = unsafe {
352-
std::slice::from_raw_parts(samples.as_ptr().cast::<tsk_id_t>(), samples.len())
353-
};
354350
let mut inner = self.inner.simplify(
355-
llsamples,
351+
samples,
356352
options.into(),
357353
match idmap {
358-
true => output_node_map.as_mut_ptr().cast::<tsk_id_t>(),
359-
false => std::ptr::null_mut(),
354+
true => Some(&mut output_node_map),
355+
false => None,
360356
},
361357
)?;
362358
let views = crate::table_views::TableViews::new_from_tree_sequence(inner.as_mut())?;

0 commit comments

Comments
 (0)