From 50e5e391743d55df9862d141fe01c2a06041b07e Mon Sep 17 00:00:00 2001 From: Leo Collins Date: Wed, 17 Jun 2026 12:33:25 +0100 Subject: [PATCH 1/4] use i64 for ids in interval tree --- Cargo.lock | 2 +- interval-tree/Cargo.toml | 2 +- interval-tree/src/lib.rs | 12 ++++++------ interval-tree/src/tests.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07f30ad..4da1bcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,7 +256,7 @@ dependencies = [ [[package]] name = "interval-tree" -version = "0.1.1" +version = "0.2.0" dependencies = [ "rand", ] diff --git a/interval-tree/Cargo.toml b/interval-tree/Cargo.toml index 67a9a0a..cc0aa00 100644 --- a/interval-tree/Cargo.toml +++ b/interval-tree/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "interval-tree" -version = "0.1.1" +version = "0.2.0" edition = "2024" [dependencies] diff --git a/interval-tree/src/lib.rs b/interval-tree/src/lib.rs index 03fc0f7..1d8c0ce 100644 --- a/interval-tree/src/lib.rs +++ b/interval-tree/src/lib.rs @@ -7,8 +7,8 @@ pub struct IntervalTreeNode { pub max: f64, pub left: Option>, pub right: Option>, - pub overlapping_by_min: Vec<(f64, f64, usize)>, - pub overlapping_by_max: Vec<(f64, f64, usize)>, + pub overlapping_by_min: Vec<(f64, f64, i64)>, + pub overlapping_by_max: Vec<(f64, f64, i64)>, } /// Builds an interval tree node from a list of intervals. Each interval is represented as a tuple of (min, max, id). @@ -16,7 +16,7 @@ pub struct IntervalTreeNode { /// # Panics /// /// Panics if the input list of intervals is empty. -fn build_node(intervals: Vec<(f64, f64, usize)>) -> IntervalTreeNode { +fn build_node(intervals: Vec<(f64, f64, i64)>) -> IntervalTreeNode { // This follows the algorithm described in https://en.wikipedia.org/wiki/Interval_tree assert!( !intervals.is_empty(), @@ -94,7 +94,7 @@ impl IntervalTree { /// /// Panics if the input arrays have different lengths. #[must_use] - pub fn bulk_load(mins: &[f64], maxs: &[f64], ids: &[usize]) -> Self { + pub fn bulk_load(mins: &[f64], maxs: &[f64], ids: &[i64]) -> Self { let n = mins.len(); assert!( n == maxs.len() && n == ids.len(), @@ -103,7 +103,7 @@ impl IntervalTree { if n == 0 { return Self::new(); } - let elements: Vec<(f64, f64, usize)> = (0..n).map(|i| (mins[i], maxs[i], ids[i])).collect(); + let elements: Vec<(f64, f64, i64)> = (0..n).map(|i| (mins[i], maxs[i], ids[i])).collect(); Self { root: Some(build_node(elements)), size: n, @@ -113,7 +113,7 @@ impl IntervalTree { /// Locates all intervals that contain the given point `p`. Returns a vector of the ids of the matching intervals. /// Returns an empty vector if no intervals contain the point. #[must_use] - pub fn locate_all_at_point(&self, p: f64) -> Vec { + pub fn locate_all_at_point(&self, p: f64) -> Vec { // Pre-order traversal of the interval tree let mut result = Vec::new(); let mut stack = Vec::new(); diff --git a/interval-tree/src/tests.rs b/interval-tree/src/tests.rs index 8f2c8fe..c6fb8e1 100644 --- a/interval-tree/src/tests.rs +++ b/interval-tree/src/tests.rs @@ -246,9 +246,9 @@ fn test_interval_tree_large_nonoverlapping() { let n = 500_000; let mins: Vec = (0..n).map(|i| i as f64 * 2.0).collect(); let maxs: Vec = (0..n).map(|i| i as f64 * 2.0 + 1.0).collect(); - let ids: Vec = (0..n).collect(); + let ids: Vec = (0..n).collect(); let tree = IntervalTree::bulk_load(&mins, &maxs, &ids); - assert_eq!(tree.size(), n); + assert_eq!(tree.size(), n.try_into().unwrap()); let mut rng = SmallRng::seed_from_u64(0); for _ in 0..100_000 { From cdf1eb54f7180ed288b73a661043578532da98e8 Mon Sep 17 00:00:00 2001 From: Leo Collins Date: Wed, 17 Jun 2026 13:39:42 +0100 Subject: [PATCH 2/4] change ids to i64, add free_offsets function also fixed the dim type in rtree_free_bounding_boxes --- rtree-capi/include/rtree-capi.h | 19 ++++++++----- rtree-capi/src/rtree.rs | 50 ++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/rtree-capi/include/rtree-capi.h b/rtree-capi/include/rtree-capi.h index 4349a4d..0a7f584 100644 --- a/rtree-capi/include/rtree-capi.h +++ b/rtree-capi/include/rtree-capi.h @@ -26,7 +26,7 @@ typedef struct RTreeNodeH RTreeNodeH; RTreeError rtree_bulk_load(struct RTreeH **tree, const double *mins, const double *maxs, - const size_t *ids, + const int64_t *ids, size_t n, uint32_t dim); @@ -59,12 +59,17 @@ RTreeError rtree_free(struct RTreeH *tree); /** * Frees the bounding boxes returned by `rtree_collect_bounding_boxes`. */ -RTreeError rtree_free_bounding_boxes(double *mins, double *maxs, size_t n_boxes, size_t dim); +RTreeError rtree_free_bounding_boxes(double *mins, double *maxs, size_t n_boxes, uint32_t dim); /** * Frees the ids returned by `rtree_locate_all_at_point`. */ -RTreeError rtree_free_ids(size_t *ids, size_t n); +RTreeError rtree_free_ids(int64_t *ids, size_t n); + +/** + * Frees the offsets returned by `rtree_locate_all_at_points`. + */ +RTreeError rtree_free_offsets(size_t *offsets, size_t n); /** * Returns the dimension of the tree. @@ -78,7 +83,7 @@ RTreeError rtree_get_dimension(const struct RTreeH *tree, uint32_t *dim); */ RTreeError rtree_locate_all_at_point(const struct RTreeH *tree, const double *point, - size_t **ids_out, + int64_t **ids_out, size_t *nids_out); /** @@ -87,13 +92,13 @@ RTreeError rtree_locate_all_at_point(const struct RTreeH *tree, * The candidate ids are returned in `ids_out`, and `offsets_out` * is an array of length `n_points + 1` such that the ids for point `i` are * `ids_out[offsets_out[i]..offsets_out[i + 1]]`. - * You must free `ids_out` (with length `offsets_out[n_points]`) and `offsets_out` - * (with length `n_points + 1`) with `rtree_free_ids`. + * You must free `ids_out` (with length `offsets_out[n_points]`) with `rtree_free_ids`, + * and `offsets_out` (with length `n_points + 1`) with `rtree_free_offsets`. */ RTreeError rtree_locate_all_at_points(const struct RTreeH *tree, const double *points, size_t n_points, - size_t **ids_out, + int64_t **ids_out, size_t **offsets_out); /** diff --git a/rtree-capi/src/rtree.rs b/rtree-capi/src/rtree.rs index 9933432..e685df8 100644 --- a/rtree-capi/src/rtree.rs +++ b/rtree-capi/src/rtree.rs @@ -4,8 +4,8 @@ use interval_tree::{IntervalTree, IntervalTreeNode}; use crate::error::RTreeError; -pub type Object2D = GeomWithData, usize>; -pub type Object3D = GeomWithData, usize>; +pub type Object2D = GeomWithData, i64>; +pub type Object3D = GeomWithData, i64>; pub enum RTreeDim { D1(IntervalTree), @@ -42,7 +42,7 @@ pub extern "C" fn rtree_free(tree: *mut RTreeH) -> RTreeError { RTreeError::Success } -fn _rtree_get_dimension(tree: &RTreeDim) -> u32 { +fn _rtree_get_dimension(tree: &RTreeDim) -> usize { match tree { RTreeDim::D1(_) => 1, RTreeDim::D2(_) => 2, @@ -57,16 +57,16 @@ pub extern "C" fn rtree_get_dimension(tree: *const RTreeH, dim: *mut u32) -> RTr return RTreeError::NullPointer; } let rtree = unsafe { &*(tree as *const RTreeDim) }; - unsafe { *dim = _rtree_get_dimension(rtree) }; + unsafe { *dim = _rtree_get_dimension(rtree) as u32 }; RTreeError::Success } fn _rtree_bulk_load( mins: *const f64, maxs: *const f64, - data: *const usize, + data: *const i64, n: usize, -) -> RTree, usize>> { +) -> RTree, i64>> { let mins = unsafe { std::slice::from_raw_parts(mins, n * DIM) }; let maxs = unsafe { std::slice::from_raw_parts(maxs, n * DIM) }; let data = unsafe { std::slice::from_raw_parts(data, n) }; @@ -85,7 +85,7 @@ fn _rtree_bulk_load( fn _interval_tree_bulk_load( mins: *const f64, maxs: *const f64, - data: *const usize, + data: *const i64, n: usize, ) -> IntervalTree { let mins = unsafe { std::slice::from_raw_parts(mins, n) }; @@ -104,7 +104,7 @@ pub extern "C" fn rtree_bulk_load( tree: *mut *mut RTreeH, mins: *const f64, maxs: *const f64, - ids: *const usize, + ids: *const i64, n: usize, dim: u32, ) -> RTreeError { @@ -145,14 +145,14 @@ pub extern "C" fn rtree_bulk_load( pub extern "C" fn rtree_locate_all_at_point( tree: *const RTreeH, point: *const f64, - ids_out: *mut *mut usize, + ids_out: *mut *mut i64, nids_out: *mut usize, ) -> RTreeError { if tree.is_null() || point.is_null() || ids_out.is_null() || nids_out.is_null() { return RTreeError::NullPointer; } let rtree = unsafe { &*(tree as *const RTreeDim) }; - let mut ids: Vec = match rtree { + let mut ids: Vec = match rtree { RTreeDim::D1(tree) => { let p: f64 = unsafe { *point }; tree.locate_all_at_point(p) @@ -183,14 +183,14 @@ pub extern "C" fn rtree_locate_all_at_point( /// The candidate ids are returned in `ids_out`, and `offsets_out` /// is an array of length `n_points + 1` such that the ids for point `i` are /// `ids_out[offsets_out[i]..offsets_out[i + 1]]`. -/// You must free `ids_out` (with length `offsets_out[n_points]`) and `offsets_out` -/// (with length `n_points + 1`) with `rtree_free_ids`. +/// You must free `ids_out` (with length `offsets_out[n_points]`) with `rtree_free_ids`, +/// and `offsets_out` (with length `n_points + 1`) with `rtree_free_offsets`. #[no_mangle] pub extern "C" fn rtree_locate_all_at_points( tree: *const RTreeH, points: *const f64, n_points: usize, - ids_out: *mut *mut usize, + ids_out: *mut *mut i64, offsets_out: *mut *mut usize, ) -> RTreeError { if tree.is_null() || ids_out.is_null() || offsets_out.is_null() { @@ -200,9 +200,9 @@ pub extern "C" fn rtree_locate_all_at_points( return RTreeError::NullPointer; } let rtree = unsafe { &*(tree as *const RTreeDim) }; - let dim = _rtree_get_dimension(rtree) as usize; + let dim = _rtree_get_dimension(rtree); - let mut ids: Vec = Vec::new(); + let mut ids: Vec = Vec::new(); let mut offsets: Vec = Vec::with_capacity(n_points + 1); offsets.push(0); @@ -306,7 +306,7 @@ pub extern "C" fn rtree_depth(tree: *const RTreeH, depth_out: *mut usize) -> RTr } fn collect_rtree_bounding_boxes( - tree: &RTree, usize>>, + tree: &RTree, i64>>, level: usize, ) -> Vec> { if tree.size() == 0 { @@ -317,7 +317,7 @@ fn collect_rtree_bounding_boxes( return vec![root.envelope()]; } - let mut nodes: Vec<&RTreeNode, usize>>> = + let mut nodes: Vec<&RTreeNode, i64>>> = root.children().iter().collect(); for _ in 1..level { @@ -418,9 +418,9 @@ pub extern "C" fn rtree_free_bounding_boxes( mins: *mut f64, maxs: *mut f64, n_boxes: usize, - dim: usize, + dim: u32, ) -> RTreeError { - let Some(n) = n_boxes.checked_mul(dim) else { + let Some(n) = n_boxes.checked_mul(dim as usize) else { return RTreeError::InvalidDimension; }; if n > 0 && (mins.is_null() || maxs.is_null()) { @@ -437,10 +437,20 @@ pub extern "C" fn rtree_free_bounding_boxes( /// Frees the ids returned by `rtree_locate_all_at_point`. #[no_mangle] -pub extern "C" fn rtree_free_ids(ids: *mut usize, n: usize) -> RTreeError { +pub extern "C" fn rtree_free_ids(ids: *mut i64, n: usize) -> RTreeError { if ids.is_null() { return RTreeError::NullPointer; } unsafe { drop(Vec::from_raw_parts(ids, n, n)) }; RTreeError::Success } + +/// Frees the offsets returned by `rtree_locate_all_at_points`. +#[no_mangle] +pub extern "C" fn rtree_free_offsets(offsets: *mut usize, n: usize) -> RTreeError { + if offsets.is_null() { + return RTreeError::NullPointer; + } + unsafe { drop(Vec::from_raw_parts(offsets, n, n)) }; + RTreeError::Success +} \ No newline at end of file From 4e014e7d16e0da0071f35e0e87093f84c085f50a Mon Sep 17 00:00:00 2001 From: Leo Collins Date: Wed, 17 Jun 2026 13:39:45 +0100 Subject: [PATCH 3/4] fix tests --- rtree-capi/tests/test.c | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/rtree-capi/tests/test.c b/rtree-capi/tests/test.c index 5a22192..fc2d3ee 100644 --- a/rtree-capi/tests/test.c +++ b/rtree-capi/tests/test.c @@ -87,7 +87,7 @@ bool test_bulk_load(void) { const uint32_t dim = 2; double mins[4] = {0.0, 0.0, 1.0, 1.0}; double maxs[4] = {2.0, 2.0, 3.0, 3.0}; - size_t ids[2] = {1, 2}; + int64_t ids[2] = {1, 2}; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -115,7 +115,7 @@ bool test_bulk_load(void) { double point2[2] = {0.0, 0.0}; double point3[2] = {-1.0, 0.0}; - size_t *ids_out1 = NULL; + int64_t *ids_out1 = NULL; size_t nids_out1 = 0; rtree_locate_all_at_point(tree, point1, &ids_out1, &nids_out1); if (nids_out1 != 2 || ids_out1[0] != 2 || ids_out1[1] != 1) { @@ -127,7 +127,7 @@ bool test_bulk_load(void) { rtree_free_ids(ids_out1, nids_out1); } - size_t *ids_out2 = NULL; + int64_t *ids_out2 = NULL; size_t nids_out2 = 0; rtree_locate_all_at_point(tree, point2, &ids_out2, &nids_out2); if (nids_out2 != 1 || ids_out2[0] != 1) { @@ -139,7 +139,7 @@ bool test_bulk_load(void) { rtree_free_ids(ids_out2, nids_out2); } - size_t *ids_out3 = NULL; + int64_t *ids_out3 = NULL; size_t nids_out3 = 0; rtree_locate_all_at_point(tree, point3, &ids_out3, &nids_out3); if (nids_out3 != 0) { @@ -161,7 +161,7 @@ bool test_nodes(void) { const uint32_t dim = 2; double mins[4] = {0.0, 0.0, 1.0, 1.0}; double maxs[4] = {2.0, 2.0, 3.0, 3.0}; - size_t ids[2] = {1, 2}; + int64_t ids[2] = {1, 2}; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -305,7 +305,7 @@ bool test_rtree_1d(void) { const uint32_t dim = 1; double mins[4] = {0.0, 1.0, 2.0, 3.0}; double maxs[4] = {1.0, 2.0, 4.0, 4.0}; - size_t ids[4] = {1, 2, 3, 4}; + int64_t ids[4] = {1, 2, 3, 4}; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -335,7 +335,7 @@ bool test_rtree_1d(void) { double point3[1] = {3.5}; double point4[1] = {4.5}; - size_t *ids_out1 = NULL; + int64_t *ids_out1 = NULL; size_t nids_out1 = 0; rtree_locate_all_at_point(tree, point1, &ids_out1, &nids_out1); if (nids_out1 != 1 || ids_out1[0] != 1) { @@ -347,7 +347,7 @@ bool test_rtree_1d(void) { rtree_free_ids(ids_out1, nids_out1); } - size_t *ids_out2 = NULL; + int64_t *ids_out2 = NULL; size_t nids_out2 = 0; rtree_locate_all_at_point(tree, point2, &ids_out2, &nids_out2); if (nids_out2 != 1 || ids_out2[0] != 2) { @@ -359,7 +359,7 @@ bool test_rtree_1d(void) { rtree_free_ids(ids_out2, nids_out2); } - size_t *ids_out3 = NULL; + int64_t *ids_out3 = NULL; size_t nids_out3 = 0; rtree_locate_all_at_point(tree, point3, &ids_out3, &nids_out3); if (nids_out3 != 2 || ids_out3[1] != 4 || ids_out3[0] != 3) { @@ -371,7 +371,7 @@ bool test_rtree_1d(void) { rtree_free_ids(ids_out3, nids_out3); } - size_t *ids_out4 = NULL; + int64_t *ids_out4 = NULL; size_t nids_out4 = 0; rtree_locate_all_at_point(tree, point4, &ids_out4, &nids_out4); if (nids_out4 != 0) { @@ -392,7 +392,7 @@ bool test_rtree_node_1d(void) { const uint32_t dim = 1; double mins[5] = {0.0, 0.5, 1.0, -1.0, -2.0}; double maxs[5] = {1.0, 1.5, 2.0, 0.5, -1.0}; - size_t ids[5] = {0, 1, 2, 3, 4}; + int64_t ids[5] = {0, 1, 2, 3, 4}; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -514,7 +514,7 @@ bool test_rtree_empty(void) { const uint32_t dim = 2; double *mins = NULL; double *maxs = NULL; - size_t *ids = NULL; + int64_t *ids = NULL; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -541,7 +541,7 @@ bool test_rtree_empty(void) { // Query empty tree double point[2] = {0.0, 0.0}; - size_t *ids_out = NULL; + int64_t *ids_out = NULL; size_t nids_out = 0; rtree_locate_all_at_point(tree, point, &ids_out, &nids_out); if (nids_out != 0) { @@ -605,7 +605,7 @@ bool test_rtree_empty_1d(void) { const uint32_t dim = 1; double *mins = NULL; double *maxs = NULL; - size_t *ids = NULL; + int64_t *ids = NULL; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -631,7 +631,7 @@ bool test_rtree_empty_1d(void) { // Query empty tree double point[1] = {0.0}; - size_t *ids_out = NULL; + int64_t *ids_out = NULL; size_t nids_out = 0; rtree_locate_all_at_point(tree, point, &ids_out, &nids_out); if (nids_out != 0) { @@ -693,7 +693,7 @@ bool test_rtree_singleton_depth(void) { const uint32_t dim = 2; double mins[2] = {0.0, 0.0}; double maxs[2] = {1.0, 1.0}; - size_t ids[1] = {1}; + int64_t ids[1] = {1}; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -740,7 +740,7 @@ bool test_rtree_depth(void) { const uint32_t dim = 2; double mins[12]; double maxs[12]; - size_t ids[6]; + int64_t ids[6]; for (size_t i = 0; i < N; i++) { mins[2*i] = (double)i; mins[2*i + 1] = (double)i; @@ -766,7 +766,7 @@ bool test_rtree_depth(void) { const size_t N1 = 7; double mins1[14]; double maxs1[14]; - size_t ids1[7]; + int64_t ids1[7]; for (size_t i = 0; i < N1; i++) { mins1[2*i] = (double)i; mins1[2*i + 1] = (double)i; @@ -797,7 +797,7 @@ bool test_locate_all_at_points(void) { const uint32_t dim = 2; double mins[4] = {0.0, 0.0, 1.0, 1.0}; double maxs[4] = {2.0, 2.0, 3.0, 3.0}; - size_t ids[2] = {1, 2}; + int64_t ids[2] = {1, 2}; RTreeH *tree = NULL; rtree_bulk_load(&tree, mins, maxs, ids, N, dim); if (tree == NULL) { @@ -811,7 +811,7 @@ bool test_locate_all_at_points(void) { -1.0, 0.0, // none }; - size_t *ids_out = NULL; + int64_t *ids_out = NULL; size_t *offsets_out = NULL; RTreeError err = rtree_locate_all_at_points(tree, points, n_points, &ids_out, &offsets_out); if (err != Success) { @@ -827,29 +827,29 @@ bool test_locate_all_at_points(void) { fprintf(stderr, "Expected offsets[%zu] = %zu, got %zu\n", i, expected_offsets[i], offsets_out[i]); rtree_free_ids(ids_out, offsets_out[n_points]); - rtree_free_ids(offsets_out, n_points + 1); + rtree_free_offsets(offsets_out, n_points + 1); rtree_free(tree); return false; } } - size_t expected_ids[3] = {2, 1, 1}; + int64_t expected_ids[3] = {2, 1, 1}; for (size_t i = 0; i < offsets_out[n_points]; i++) { if (ids_out[i] != expected_ids[i]) { - fprintf(stderr, "Expected ids[%zu] = %zu, got %zu\n", + fprintf(stderr, "Expected ids[%zu] = %lld, got %lld\n", i, expected_ids[i], ids_out[i]); rtree_free_ids(ids_out, offsets_out[n_points]); - rtree_free_ids(offsets_out, n_points + 1); + rtree_free_offsets(offsets_out, n_points + 1); rtree_free(tree); return false; } } rtree_free_ids(ids_out, offsets_out[n_points]); - rtree_free_ids(offsets_out, n_points + 1); + rtree_free_offsets(offsets_out, n_points + 1); // A zero-point query should return valid offsets = [0] and no ids. - size_t *ids_out0 = NULL; + int64_t *ids_out0 = NULL; size_t *offsets_out0 = NULL; err = rtree_locate_all_at_points(tree, NULL, 0, &ids_out0, &offsets_out0); if (err != Success) { @@ -860,12 +860,12 @@ bool test_locate_all_at_points(void) { if (offsets_out0[0] != 0) { fprintf(stderr, "Expected offsets[0] = 0 for zero-point query, got %zu\n", offsets_out0[0]); rtree_free_ids(ids_out0, offsets_out0[0]); - rtree_free_ids(offsets_out0, 1); + rtree_free_offsets(offsets_out0, 1); rtree_free(tree); return false; } rtree_free_ids(ids_out0, offsets_out0[0]); - rtree_free_ids(offsets_out0, 1); + rtree_free_offsets(offsets_out0, 1); rtree_free(tree); return true; From 8bc69e99bdd5e084730ed84ed8857bff41056672 Mon Sep 17 00:00:00 2001 From: Leo Collins Date: Wed, 17 Jun 2026 14:10:27 +0100 Subject: [PATCH 4/4] use correct format specifier --- rtree-capi/tests/test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtree-capi/tests/test.c b/rtree-capi/tests/test.c index fc2d3ee..bc6ba80 100644 --- a/rtree-capi/tests/test.c +++ b/rtree-capi/tests/test.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "rtree-capi.h" @@ -836,7 +837,7 @@ bool test_locate_all_at_points(void) { int64_t expected_ids[3] = {2, 1, 1}; for (size_t i = 0; i < offsets_out[n_points]; i++) { if (ids_out[i] != expected_ids[i]) { - fprintf(stderr, "Expected ids[%zu] = %lld, got %lld\n", + fprintf(stderr, "Expected ids[%zu] = %" PRId64 ", got %" PRId64 "\n", i, expected_ids[i], ids_out[i]); rtree_free_ids(ids_out, offsets_out[n_points]); rtree_free_offsets(offsets_out, n_points + 1);