Skip to content

Commit 57f34bd

Browse files
committed
rename findleaf() into Base.findfirst()
It better matches what the method does. Add basic findfirst() tests. Fix isequal_rtree() so if key=nothing is supplied for trees with ids, the key is not checked.
1 parent 6e96562 commit 57f34bd

5 files changed

Lines changed: 54 additions & 17 deletions

File tree

src/rtree/bulk.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function omt_subtree(elems::AbstractVector, tree::RTree,
9797
child = omt_subtree(elems, tree, lev - 1, nslices, nsubtrees,
9898
leaf_fill, branch_fill)
9999
node = _attach!(acquire(tree, Branch, lev), child, tree)
100-
tree.nnodes_perlevel[lev-1] += 1
100+
tree.nnodes_perlevel[lev - 1] += 1
101101
return node
102102
end
103103
end

src/rtree/delete.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Deletes the value identified by `br` bounding box (or point `pt`) and
66
the `id` (if tree elements support `HasID` trait) from the `tree`.
77
"""
88
function Base.delete!(tree::RTree{T,N}, br::Rect{T,N}, id::Any = nothing) where {T,N}
9-
leafx = findleaf(tree, br, id)
9+
leafx = findfirst(tree, br, id)
1010
leafx === nothing && __spatial_keyerror(eltype(tree), br, id)
1111
_detach!(leafx[1], leafx[2], tree)
1212
tmpdetached = Vector{nodetype(tree)}() # FIXME use pool, Union{Leaf,Branch} ?

src/rtree/node.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ isequal_rtree(el::Any, reg::Region, id::Any = nothing) =
4040
isequal_rtree(::Type{<:HasID}, el::Any, reg::Region, key::Any) =
4141
isequal(id(el), convert(idtype(idtrait(typeof(el))), key)) && (mbr(el) == reg)
4242

43+
# if the tree has IDs but `nothing` supplied, skip ID check
44+
isequal_rtree(::Type{<:HasID}, el::Any, reg::Region, ::Nothing = nothing) =
45+
(mbr(el) == reg)
46+
4347
isequal_rtree(::Type{HasNoID}, el::Any, reg::Region, ::Nothing = nothing) =
4448
(mbr(el) == reg)
4549

src/rtree/query.jl

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
"""
2-
Find `Leaf` in the `node` subtree by the `id` and `br` MBR of one of its `Elem`s.
3-
4-
Returns the tuple of `Leaf` and element position or `nothing`.
5-
"""
6-
function findleaf(node::Leaf{T,N}, reg::Region{T,N}, id::Any) where {T,N}
1+
function Base.findfirst(node::Leaf{T,N}, reg::Region{T,N}, id::Any) where {T,N}
72
for (i, el) in enumerate(children(node))
83
if isequal_rtree(el, reg, id)
94
return (node, i)
@@ -12,10 +7,10 @@ function findleaf(node::Leaf{T,N}, reg::Region{T,N}, id::Any) where {T,N}
127
return nothing
138
end
149

15-
function findleaf(node::Branch{T,N,V}, reg::Region{T,N}, id::Any) where {T,N,V}
10+
function Base.findfirst(node::Branch{T,N,V}, reg::Region{T,N}, id::Any) where {T,N,V}
1611
for child in children(node)
1712
if contains(mbr(child), reg)
18-
res = findleaf(child, reg, id)
13+
res = findfirst(child, reg, id)
1914
if res !== nothing
2015
return res::Tuple{Leaf{T,N,V}, Int}
2116
end
@@ -24,8 +19,16 @@ function findleaf(node::Branch{T,N,V}, reg::Region{T,N}, id::Any) where {T,N,V}
2419
return nothing
2520
end
2621

27-
findleaf(rtree::RTree{T,N}, reg::Region{T,N}, id::Any = nothing) where {T,N} =
28-
findleaf(rtree.root, reg, id)
22+
"""
23+
findfirst(tree::RTree{T,N}, reg::Region{T,N}, [id]) where {T,N}
24+
25+
Find the element in the `tree` by its region (`reg`) and, optionally, its `id`.
26+
The region (MBR) of the element and `reg` should match exactly.
27+
28+
Returns the tuple of `Leaf` and position of the element or `nothing`.
29+
"""
30+
Base.findfirst(tree::RTree{T,N}, reg::Region{T,N}, id::Any = nothing) where {T,N} =
31+
findfirst(tree.root, reg, id)
2932

3033
# FIXME: currently isempty() doesn't allow specifying how
3134
# to treat overlapping elements (inside or not), currently treated as outside

test/rtree.jl

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ end
8484
@test length(collect(intersects_with(tree, SI.Rect((0.0, 0.0), (0.6, 0.6))))) == 2
8585
@test length(collect(contained_in(tree, SI.Rect((0.0, 0.0), (0.55, 0.55))))) == 1 # a only
8686
@test length(collect(intersects_with(tree, SI.Rect((0.0, 0.0), (0.55, 0.55))))) == 2 # a and c
87+
88+
@testset "findfirst()" begin
89+
@test findfirst(tree, ambr, 2) === nothing
90+
@test_throws MethodError findfirst(tree, ambr, "1") # wrong key type
91+
@test_throws MethodError findfirst(tree, SI.empty(SI.Rect{Int,2}()))
92+
@test findfirst(tree, ambr, 1) == (tree.root, 2)
93+
@test findfirst(tree, ambr) == (tree.root, 2) # search without id ignores it
94+
@test findfirst(tree, bmbr, 1) === nothing
95+
@test findfirst(tree, bmbr, 2) == (tree.root, 1)
96+
@test findfirst(tree, bmbr) == (tree.root, 1)
97+
@test findfirst(tree, cmbr, 2) === nothing
98+
@test findfirst(tree, cmbr, 3) == (tree.root, 3)
99+
@test findfirst(tree, cmbr) == (tree.root, 3)
100+
@test findfirst(tree, SI.combine(ambr, cmbr)) === nothing
101+
@test findfirst(tree, SI.empty(SI.mbrtype(tree))) === nothing
102+
end
87103
end
88104

89105
@testset "RTree{Int,3,String,Nothing}(variant=$tree_var) (no id)" for tree_var in tree_vars
@@ -130,6 +146,20 @@ end
130146
@test delete!(tree, bmbr) === tree
131147
@test length(tree) == 1
132148
@test SI.check(tree)
149+
@test insert!(tree, bmbr, "4") === tree
150+
@test length(tree) == 2
151+
@test SI.check(tree)
152+
153+
@testset "findfirst()" begin
154+
@test_throws MethodError findfirst(tree, ambr, 2) # no key
155+
@test_throws MethodError findfirst(tree, ambr, "1")
156+
@test_throws MethodError findfirst(tree, SI.empty(SI.Rect{Int,2}()))
157+
@test_throws MethodError findfirst(tree, SI.empty(SI.Rect{Float64,3}()))
158+
@test findfirst(tree, ambr) == (tree.root, 1)
159+
@test findfirst(tree, bmbr) == (tree.root, 2)
160+
@test findfirst(tree, SI.combine(ambr, bmbr)) === nothing
161+
@test findfirst(tree, SI.empty(SI.mbrtype(tree))) === nothing
162+
end
133163
end
134164
end
135165

@@ -157,10 +187,10 @@ end
157187
#@show SI.height(tree)
158188
#@show tree.nnodes_perlevel
159189

160-
@testset "findleaf" begin
190+
@testset "findfirst()" begin
161191
# check that the elements can be found
162192
for i in 1:length(tree)
163-
node_ix = SI.findleaf(tree.root, mbrs[i], i)
193+
node_ix = findfirst(tree.root, mbrs[i], i)
164194
@test node_ix !== nothing
165195
if node_ix !== nothing
166196
node, ix = node_ix
@@ -201,10 +231,10 @@ end
201231
@test_throws ArgumentError SI.load!(tree, enumerate(mbrs), method=:OMT,
202232
getid = x -> x[1], getmbr = x -> x[2], getval = x -> string(x[1]))
203233

204-
@testset "findleaf" begin
234+
@testset "findfirst()" begin
205235
# check that the elements can be found
206236
for i in 1:length(tree)
207-
node_ix = SI.findleaf(tree.root, mbrs[i], i)
237+
node_ix = findfirst(tree.root, mbrs[i], i)
208238
@test node_ix !== nothing
209239
if node_ix !== nothing
210240
node, ix = node_ix
@@ -235,7 +265,7 @@ end
235265
@test length(tree) == 3
236266
@test tree.nelem_deletions == 4
237267
for i in [3, 4, 7] # check that the correct points stayed in the tree
238-
@test SI.findleaf(tree.root, SI.Rect(pts[i], pts[i]), i) !== nothing
268+
@test findfirst(tree.root, SI.Rect(pts[i], pts[i]), i) !== nothing
239269
end
240270
end
241271

0 commit comments

Comments
 (0)