Skip to content

Commit

Permalink
Fix selectindices for nothing return type (#705)
Browse files Browse the repository at this point in the history
* fix selectindices for tuples and make it fast

* test selectindices fixes
  • Loading branch information
rafaqz committed Apr 30, 2024
1 parent d8a3d4b commit 1dfd48c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
19 changes: 17 additions & 2 deletions src/Dimensions/dimension.jl
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,23 @@ end
return selectindices(dims(x), selectors; kw...)
end
end
@inline selectindices(ds::DimTuple, sel...; kw...) = selectindices(ds, sel; kw...)
@inline selectindices(ds::DimTuple, sel::Tuple; kw...) = selectindices(val(ds), sel; kw...)
@inline selectindices(ds::Tuple, sel...; kw...) = selectindices(ds, sel; kw...)
# Cant get this to compile away without a generated function
# The nothing handling is for if `err=_False`, and we want to combine
# multiple `nothing` into a single `nothing` return value
@generated function selectindices(ds::Tuple, sel::Tuple; kw...)
tuple_exp = Expr(:tuple)
for i in eachindex(ds.parameters)
expr = quote
x = selectindices(ds[$i], sel[$i]; kw...)
isnothing(x) && return nothing
x
end
push!(tuple_exp.args, expr)
end
return tuple_exp
end
@inline selectindices(ds::Tuple, sel::Tuple{}; kw...) = ()
@inline selectindices(dim::Dimension, sel; kw...) = selectindices(val(dim), sel; kw...)

# Deprecated
Expand Down
32 changes: 16 additions & 16 deletions src/Lookups/selector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const SelectorOrInterval = Union{Selector,Interval,Not}
const SelTuple = Tuple{SelectorOrInterval,Vararg{SelectorOrInterval}}

# `Not` form InvertedIndices.jr
function selectindices(l::Lookup, sel::Not; kw...)
@inline function selectindices(l::Lookup, sel::Not; kw...)
indices = selectindices(l, sel.skip; kw...)
return first(to_indices(l, (Not(indices),)))
end
Expand Down Expand Up @@ -129,10 +129,10 @@ Base.show(io::IO, x::At) = print(io, "At(", val(x), ", ", atol(x), ", ", rtol(x)
struct _True end
struct _False end

selectindices(l::Lookup, sel::At; kw...) = at(l, sel; kw...)
selectindices(l::Lookup, sel::At{<:AbstractVector}; kw...) = _selectvec(l, sel; kw...)
@inline selectindices(l::Lookup, sel::At; kw...) = at(l, sel; kw...)
@inline selectindices(l::Lookup, sel::At{<:AbstractVector}; kw...) = _selectvec(l, sel; kw...)

_selectvec(l, sel; kw...) = [selectindices(l, rebuild(sel, v); kw...) for v in val(sel)]
@inline _selectvec(l, sel; kw...) = [selectindices(l, rebuild(sel, v); kw...) for v in val(sel)]

function at(lookup::AbstractCyclic{Cycling}, sel::At; kw...)
cycled_sel = rebuild(sel, cycle_val(lookup, val(sel)))
Expand Down Expand Up @@ -261,8 +261,8 @@ struct Near{T} <: IntSelector{T}
end
Near() = Near(nothing)

selectindices(l::Lookup, sel::Near; kw...) = near(l, sel)
selectindices(l::Lookup, sel::Near{<:AbstractVector}; kw...) = _selectvec(l, sel)
@inline selectindices(l::Lookup, sel::Near; kw...) = near(l, sel)
@inline selectindices(l::Lookup, sel::Near{<:AbstractVector}; kw...) = _selectvec(l, sel)

Base.show(io::IO, x::Near) = print(io, "Near(", val(x), ")")

Expand Down Expand Up @@ -356,8 +356,8 @@ end
Contains() = Contains(nothing)

# Filter based on sampling and selector -----------------
selectindices(l::Lookup, sel::Contains; kw...) = contains(l, sel; kw...)
selectindices(l::Lookup, sel::Contains{<:AbstractVector}; kw...) = _selectvec(l, sel; kw...)
@inline selectindices(l::Lookup, sel::Contains; kw...) = contains(l, sel; kw...)
@inline selectindices(l::Lookup, sel::Contains{<:AbstractVector}; kw...) = _selectvec(l, sel; kw...)

Base.show(io::IO, x::Contains) = print(io, "Contains(", val(x), ")")

Expand Down Expand Up @@ -567,8 +567,8 @@ abstract type _Side end
struct _Upper <: _Side end
struct _Lower <: _Side end

selectindices(l::Lookup, sel::Union{Between{<:Tuple},Interval}) = between(l, sel)
function selectindices(lookup::Lookup, sel::Between{<:AbstractVector})
@inline selectindices(l::Lookup, sel::Union{Between{<:Tuple},Interval}) = between(l, sel)
@inline function selectindices(lookup::Lookup, sel::Between{<:AbstractVector})
inds = Int[]
for v in val(sel)
append!(inds, selectindices(lookup, rebuild(sel, v)))
Expand Down Expand Up @@ -822,8 +822,8 @@ Touches(a, b) = Touches((a, b))
Base.first(sel::Touches) = first(val(sel))
Base.last(sel::Touches) = last(val(sel))

selectindices(l::Lookup, sel::Touches) = touches(l, sel)
function selectindices(lookup::Lookup, sel::Touches{<:AbstractVector})
@inline selectindices(l::Lookup, sel::Touches) = touches(l, sel)
@inline function selectindices(lookup::Lookup, sel::Touches{<:AbstractVector})
inds = Int[]
for v in val(sel)
append!(inds, selectindices(lookup, rebuild(sel, v)))
Expand Down Expand Up @@ -1141,9 +1141,9 @@ _in(needle::Interval{<:Any,:open}, haystack::Interval{:closed,:open}) = needle.l
_in(needle::Interval{:open,<:Any}, haystack::Interval{:open,:closed}) = needle.left in haystack && needle.right in haystack
_in(needle::OpenInterval, haystack::OpenInterval) = needle.left in haystack && needle.right in haystack

hasselection(lookup::Lookup, sel::At) = at(lookup, sel; err=_False()) === nothing ? false : true
hasselection(lookup::Lookup, sel::Contains) = contains(lookup, sel; err=_False()) === nothing ? false : true
@inline hasselection(lookup::Lookup, sel::At) = at(lookup, sel; err=_False()) === nothing ? false : true
@inline hasselection(lookup::Lookup, sel::Contains) = contains(lookup, sel; err=_False()) === nothing ? false : true
# Near and Between only fail on Unordered
# Otherwise Near returns the nearest index, and Between an empty range
hasselection(lookup::Lookup, ::Near) = isordered(lookup) ? true : false
hasselection(lookup::Lookup, ::Union{Interval,Between}) = isordered(lookup) ? true : false
@inline hasselection(lookup::Lookup, ::Near) = isordered(lookup) ? true : false
@inline hasselection(lookup::Lookup, ::Union{Interval,Between}) = isordered(lookup) ? true : false
4 changes: 4 additions & 0 deletions test/selector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,11 @@ end

@testset "selectindices" begin
@test selectindices(A[X(1)], Contains(7)) == (3,)
@test selectindices(A, (At(10), Contains(7))) == (1, 3)
@test selectindices(dims_, ()) == ()
@test selectindices((), ()) == ()
@test selectindices(A, (At(90), Contains(7)); err=Lookups._False()) == nothing
@test selectindices(A[X(1)], Contains(10); err=Lookups._False()) == nothing
end

@testset "hasselection" begin
Expand Down

0 comments on commit 1dfd48c

Please sign in to comment.