diff --git a/Project.toml b/Project.toml index 5eec42f..062715c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "IndexedTables" uuid = "6deec6e2-d858-57c5-ab9b-e6ca5bd20e43" -version = "1.0.1" +version = "1.0.2" [deps] DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" @@ -27,7 +27,7 @@ IteratorInterfaceExtensions = "0.1.1, 1" OnlineStatsBase = "1" PooledArrays = "0.4.1, 0.5, 1.0" StatsBase = "0.32, 0.33, 0.34" -StructArrays = "0.4.1" +StructArrays = "0.5" TableTraits = "0.3, 0.4, 1" TableTraitsUtils = "0.2.1, 0.3, 0.4, 1" Tables = "0.2.4, 1" diff --git a/src/IndexedTables.jl b/src/IndexedTables.jl index ade1028..1948199 100644 --- a/src/IndexedTables.jl +++ b/src/IndexedTables.jl @@ -4,7 +4,8 @@ using PooledArrays, SparseArrays, Statistics, WeakRefStrings using OnlineStatsBase: OnlineStat, fit! -using StructArrays: StructVector, StructArray, fieldarrays, +import StructArrays +using StructArrays: StructVector, StructArray, refine_perm!, collect_structarray, append!!, replace_storage, GroupPerm, roweq, index_type diff --git a/src/columns.jl b/src/columns.jl index b63b30c..10c7bb8 100644 --- a/src/columns.jl +++ b/src/columns.jl @@ -51,8 +51,8 @@ available selection options and syntax. """ function columns end -columns(c::Columns) = fieldarrays(c) -columns(c::Columns{<:Tuple}) = Tuple(fieldarrays(c)) +columns(c::Columns) = StructArrays.components(c) +columns(c::Columns{<:Tuple}) = Tuple(StructArrays.components(c)) columns(c::Columns{<:Pair}) = c.first => c.second """ @@ -75,7 +75,7 @@ summary(c::Columns{D}) where {D<:Tuple} = "$(length(c))-element Columns{$D}" _sizehint!(c::Columns, n::Integer) = (foreach(x->_sizehint!(x,n), columns(c)); c) function _strip_pair(c::Columns{<:Pair}) - f, s = map(columns, fieldarrays(c)) + f, s = map(columns, StructArrays.components(c)) (f isa AbstractVector) && (f = (f,)) (s isa AbstractVector) && (s = (s,)) Columns((f..., s...)) @@ -104,15 +104,15 @@ pushrow!(to::AbstractArray, from::AbstractArray, i) = push!(to, from[i]) @generated function row_asof(c::Columns{D,C}, i, d::Columns{D,C}, j) where {D,C} N = length(C.parameters) if N == 1 - ex = :(!isless(getfield(fieldarrays(c),1)[i], getfield(fieldarrays(d),1)[j])) + ex = :(!isless(getfield(StructArrays.components(c),1)[i], getfield(StructArrays.components(d),1)[j])) else - ex = :(isequal(getfield(fieldarrays(c),1)[i], getfield(fieldarrays(d),1)[j])) + ex = :(isequal(getfield(StructArrays.components(c),1)[i], getfield(StructArrays.components(d),1)[j])) end for n in 2:N if N == n - ex = :(($ex) && !isless(getfield(fieldarrays(c),$n)[i], getfield(fieldarrays(d),$n)[j])) + ex = :(($ex) && !isless(getfield(StructArrays.components(c),$n)[i], getfield(StructArrays.components(d),$n)[j])) else - ex = :(($ex) && isequal(getfield(fieldarrays(c),$n)[i], getfield(fieldarrays(d),$n)[j])) + ex = :(($ex) && isequal(getfield(StructArrays.components(c),$n)[i], getfield(StructArrays.components(d),$n)[j])) end end ex @@ -222,7 +222,7 @@ column(c, x) = columns(c)[colindex(c, x)] # optimized method @inline function column(c::Columns, x::Union{Int, Symbol}) - getfield(fieldarrays(c), x) + getfield(StructArrays.components(c), x) end column(t, a::AbstractArray) = a @@ -624,5 +624,5 @@ function init_inputs(f::Tup, input, isvec) end # utils -refs(v::Columns) = Columns(map(refs, fieldarrays(v))) +refs(v::Columns) = Columns(map(refs, StructArrays.components(v))) compact_mem(v::Columns) = replace_storage(compact_mem, v) diff --git a/src/join.jl b/src/join.jl index 4a22ea2..6716893 100644 --- a/src/join.jl +++ b/src/join.jl @@ -10,8 +10,8 @@ function rowcmp(tc::Tuple, i, td::Tuple, j) end function rowcmp(c::Columns, i, d::Columns, j) - tc = Tuple(fieldarrays(c)) - td = Tuple(fieldarrays(d)) + tc = Tuple(StructArrays.components(c)) + td = Tuple(StructArrays.components(d)) return rowcmp(tc, i, td, j) end @@ -79,7 +79,7 @@ nullrow(T, M) = missing_instance(M) nullrowtype(::Type{T}, ::Type{S}) where {T<:Tup, S} = map_params(t -> type2missingtype(t, S), T) nullrowtype(::Type{T}, ::Type{S}) where {T, S} = type2missingtype(T, S) -nullablerows(s::Columns{C}, ::Type{S}) where {C, S} = Columns{nullrowtype(C, S)}(fieldarrays(s)) +nullablerows(s::Columns{C}, ::Type{S}) where {C, S} = Columns{nullrowtype(C, S)}(StructArrays.components(s)) nullablerows(s::AbstractVector, ::Type{S}) where {S} = vec_missing(s, S) function init_left_right(ldata::AbstractVector{L}, rdata::AbstractVector{R}) where {L, R} @@ -247,8 +247,8 @@ function Base.join(f, left::Dataset, right::Dataset; rdata = replace_placeholder(right, rdata) KT = map_params(promote_type, eltype(lkey), eltype(rkey)) - lkey = Columns{KT}(Tuple(fieldarrays(lkey))) - rkey = Columns{KT}(Tuple(fieldarrays(rkey))) + lkey = Columns{KT}(Tuple(StructArrays.components(lkey))) + rkey = Columns{KT}(Tuple(StructArrays.components(rkey))) join_iter = GroupJoinPerm(GroupPerm(lkey, lperm), GroupPerm(rkey, rperm)) init = !group && f === concat_tup ? init_left_right(ldata, rdata) : nothing typ, grp = Val{how}(), Val{group}() diff --git a/src/ndsparse.jl b/src/ndsparse.jl index 219ad87..d201705 100644 --- a/src/ndsparse.jl +++ b/src/ndsparse.jl @@ -209,7 +209,7 @@ _convert(::Type{<:Tuple}, tup::Tuple) = tup _convert(::Type{T}, tup::Tuple) where {T<:NamedTuple} = T(tup) convertkey(t::NDSparse{V,K,I}, tup::Tuple) where {V,K,I} = _convert(eltype(I), tup) -ndims(t::NDSparse) = length(fieldarrays(t.index)) +ndims(t::NDSparse) = length(StructArrays.components(t.index)) length(t::NDSparse) = (flush!(t);length(t.index)) eltype(::Type{NDSparse{T,D,C,V}}) where {T,D,C,V} = T Base.keytype(::Type{NDSparse{T,D,C,V}}) where {T,D,C,V} = D diff --git a/src/selection.jl b/src/selection.jl index ae33423..93c8db4 100644 --- a/src/selection.jl +++ b/src/selection.jl @@ -138,7 +138,7 @@ missing_indxs(v::AbstractVector) = findall(!_ismissing, v) function missing_indxs(t::StructArray) indxs = collect(1:length(t)) - for vec in getfield(t, :fieldarrays) + for vec in StructArrays.components(t) filter!(i -> !_ismissing(vec[i]), indxs) end indxs diff --git a/src/utils.jl b/src/utils.jl index 632e7ac..c8af08f 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -90,6 +90,18 @@ function namedtuple(fields...) NamedTuple{fields} end + +# not inferrable +_index_type(::Type{NamedTuple{names, types}}) where {names, types} = _index_type(types) +_index_type(::Type{Tuple{}}) = Int +function _index_type(::Type{T}) where {T<:Tuple} + S, U = Base.tuple_type_head(T), Base.tuple_type_tail(T) + return __index_type(S, U) +end +_index_type(::Type{NTuple{N, S}}) where {N, S} = __index_type(S) +__index_type(::Type{S}, ::Type{U}=Tuple{}) where {S, U} = + IndexStyle(S) isa IndexCartesian ? CartesianIndex{ndims(S)} : _index_type(U) + """ arrayof(T) @@ -102,20 +114,20 @@ Base.@pure function arrayof(S) Vector{Union{}} elseif T <: Tuple coltypes = Tuple{map(arrayof, fieldtypes(T))...} - Columns{T, coltypes, index_type(coltypes)} + Columns{T, coltypes, _index_type(coltypes)} elseif T <: NamedTuple if fieldcount(T) == 0 coltypes = NamedTuple{(), Tuple{}} - Columns{NamedTuple{(), Tuple{}}, coltypes, index_type(coltypes)} + Columns{NamedTuple{(), Tuple{}}, coltypes, _index_type(coltypes)} else coltypes = NamedTuple{fieldnames(T), Tuple{map(arrayof, fieldtypes(T))...}} - Columns{T, coltypes, index_type(coltypes)} + Columns{T, coltypes, _index_type(coltypes)} end elseif (T <: Union{Missing, String, WeakRefString} && Missing <: T) || T <: Union{String, WeakRefString} StringArray{T, 1} elseif T <: Pair coltypes = NamedTuple{(:first, :second), Tuple{map(arrayof, T.parameters)...}} - Columns{T, coltypes, index_type(coltypes)} + Columns{T, coltypes, _index_type(coltypes)} elseif T <: DataValue DataValueArray{eltype(T)} else