Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions interval-tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,7 @@ impl IntervalTree {
"Inputs must have the same length"
);
if n == 0 {
return Self {
root: None,
size: 0,
};
return Self::new();
}
let elements: Vec<(f64, f64, usize)> = (0..n).map(|i| (mins[i], maxs[i], ids[i])).collect();
Self {
Expand Down Expand Up @@ -160,6 +157,15 @@ impl IntervalTree {
pub fn root(&self) -> Option<&IntervalTreeNode> {
self.root.as_ref()
}

/// Returns an empty interval tree.
#[must_use]
pub fn new() -> Self {
Self {
root: None,
size: 0,
}
}
}

#[cfg(test)]
Expand Down
7 changes: 7 additions & 0 deletions interval-tree/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ fn test_interval_tree_bulk_load() {
assert_eq!(right_node.right, None);
}

#[test]
fn test_interval_tree_new() {
let tree = IntervalTree::new();
assert_eq!(tree.size(), 0);
assert_eq!(tree.root(), None);
}

#[test]
fn test_interval_tree_empty_bulk_load() {
let mins = vec![];
Expand Down
3 changes: 3 additions & 0 deletions rtree-capi/include/rtree-capi.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum RTreeError {
Success = 0,
NullPointer = 1,
InvalidDimension = 2,
EmptyNodeEnvelope = 3,
};
typedef uint16_t RTreeError;

Expand Down Expand Up @@ -47,3 +48,5 @@ RTreeError rtree_node_envelope(const struct RTreeNodeH *node, double *min_out, d
RTreeError rtree_node_free(struct RTreeNodeH *node);

RTreeError rtree_root_node(const struct RTreeH *tree, struct RTreeNodeH **node);

RTreeError rtree_size(const struct RTreeH *tree, size_t *size_out);
1 change: 1 addition & 0 deletions rtree-capi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub enum RTreeError {
Success = 0,
NullPointer = 1,
InvalidDimension = 2,
EmptyNodeEnvelope = 3,
}
13 changes: 13 additions & 0 deletions rtree-capi/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum NodeRef {
Parent3D(*const ParentNode<Object3D>),
Node2D(*const RTreeNode<Object2D>),
Node3D(*const RTreeNode<Object3D>),
EmptyNode, // root node of empty tree
}

pub enum RTreeNodeH {}
Expand All @@ -20,6 +21,16 @@ pub extern "C" fn rtree_root_node(tree: *const RTreeH, node: *mut *mut RTreeNode
return RTreeError::NullPointer;
}
let rtree = unsafe { &*(tree as *const RTreeDim) };
let size = match rtree {
RTreeDim::D1(tree) => tree.size(),
RTreeDim::D2(tree) => tree.size(),
RTreeDim::D3(tree) => tree.size(),
};
if size == 0 {
let node_ref = NodeRef::EmptyNode;
unsafe { *node = Box::into_raw(Box::new(node_ref)) as *mut RTreeNodeH };
return RTreeError::Success;
}
let node_ref = match rtree {
RTreeDim::D1(tree) => NodeRef::ITreeNode(tree.root().unwrap()),
RTreeDim::D2(tree) => NodeRef::Parent2D(tree.root() as *const _),
Expand All @@ -41,6 +52,7 @@ pub extern "C" fn rtree_node_children(
let node_ref = unsafe { &*(node as *const NodeRef) };

let child_node_refs: Vec<NodeRef> = match node_ref {
NodeRef::EmptyNode => Vec::new(),
NodeRef::ITreeNode(ptr) => {
let node = unsafe { &**ptr };
let mut children = Vec::new();
Expand Down Expand Up @@ -115,6 +127,7 @@ pub extern "C" fn rtree_node_envelope(
let node_ref = unsafe { &*(node as *const NodeRef) };

match node_ref {
NodeRef::EmptyNode => return RTreeError::EmptyNodeEnvelope,
NodeRef::ITreeNode(ptr) => {
let node = unsafe { &**ptr };
let min = node.min;
Expand Down
32 changes: 31 additions & 1 deletion rtree-capi/src/rtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,22 @@ pub extern "C" fn rtree_bulk_load(
n: usize,
dim: u32,
) -> RTreeError {
if tree.is_null() || mins.is_null() || maxs.is_null() || ids.is_null() {
if tree.is_null() {
return RTreeError::NullPointer;
}

if n == 0 {
let rtree = match dim {
1 => RTreeDim::D1(IntervalTree::new()),
2 => RTreeDim::D2(RTree::new()),
3 => RTreeDim::D3(RTree::new()),
_ => return RTreeError::InvalidDimension,
};
unsafe { *tree = Box::into_raw(Box::new(rtree)) as *mut RTreeH };
return RTreeError::Success;
}

if mins.is_null() || maxs.is_null() || ids.is_null() {
return RTreeError::NullPointer;
}

Expand Down Expand Up @@ -153,6 +168,21 @@ pub extern "C" fn rtree_locate_all_at_point(
RTreeError::Success
}

#[no_mangle]
pub extern "C" fn rtree_size(tree: *const RTreeH, size_out: *mut usize) -> RTreeError {
if tree.is_null() || size_out.is_null() {
return RTreeError::NullPointer;
}
let rtree = unsafe { &*(tree as *const RTreeDim) };
let size = match rtree {
RTreeDim::D1(tree) => tree.size(),
RTreeDim::D2(tree) => tree.size(),
RTreeDim::D3(tree) => tree.size(),
};
unsafe { *size_out = size };
RTreeError::Success
}

#[no_mangle]
pub extern "C" fn rtree_free_ids(ids: *mut usize, n: usize) -> RTreeError {
if ids.is_null() {
Expand Down
Loading
Loading