Skip to content

Commit

Permalink
IndexedArray is done.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpivarski committed Aug 22, 2023
1 parent 4406f1d commit 8087ee3
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 67 deletions.
159 changes: 92 additions & 67 deletions src/AwkwardArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -596,73 +596,6 @@ function Base.getindex(
).data
end

### IndexedArray #########################################################

struct IndexedArray{INDEX<:IndexBig,CONTENT<:Content,BEHAVIOR} <: Content{BEHAVIOR}
index::INDEX
content::CONTENT
parameters::Parameters
IndexedArray(
index::INDEX,
content::CONTENT;
parameters::Parameters = Parameters(),
behavior::Symbol = :default,
) where {INDEX<:IndexBig,CONTENT<:Content} =
new{INDEX,CONTENT,behavior}(index, content, parameters)
end

IndexedArray{INDEX,CONTENT}(;
parameters::Parameters = Parameters(),
behavior::Symbol = :default,
) where {INDEX<:IndexBig} where {CONTENT<:Content} =
IndexedArray(INDEX([]), CONTENT(), parameters = parameters, behavior = behavior)

function copy(
layout::IndexedArray{INDEX1,CONTENT1,BEHAVIOR};
index::Union{Unset,INDEX2} = Unset(),
content::Union{Unset,CONTENT2} = Unset(),
parameters::Union{Unset,Parameters} = Unset(),
behavior::Union{Unset,Symbol} = Unset(),
) where {INDEX1<:IndexBig,INDEX2<:IndexBig,CONTENT1<:Content,CONTENT2<:Content,BEHAVIOR}
if isa(index, Unset)
index = layout.index
end
if isa(content, Unset)
content = layout.content
end
if isa(parameters, Unset)
parameters = parameters_of(layout)
end
if isa(behavior, Unset)
behavior = typeof(layout).parameters[end]
end
IndexedArray(index, content, parameters = parameters, behavior = behavior)
end

function is_valid(layout::IndexedArray)
for i in eachindex(layout.index)
if layout.index[i] >= length(layout.content)
return false
end
end
return is_valid(layout.content)
end

Base.length(layout::IndexedArray) = length(layout.index)
Base.firstindex(layout::IndexedArray) = firstindex(layout.index)
Base.lastindex(layout::IndexedArray) = lastindex(layout.index)

Base.getindex(layout::IndexedArray, i::Int) =
layout.content[layout.index[i]+firstindex(layout.content)]

Base.getindex(layout::IndexedArray, r::UnitRange{Int}) =
copy(layout, index = layout.index[r.start:r.stop])

Base.getindex(layout::IndexedArray, f::Symbol) = copy(layout, content = layout.content[f])




### RecordArray ##########################################################

mutable struct RecordArray{CONTENTS<:NamedTuple,BEHAVIOR} <: Content{BEHAVIOR}
Expand Down Expand Up @@ -785,4 +718,96 @@ function end_record!(layout::RecordArray)
layout
end

### IndexedArray #########################################################

struct IndexedArray{INDEX<:IndexBig,CONTENT<:Content,BEHAVIOR} <: Content{BEHAVIOR}
index::INDEX
content::CONTENT
parameters::Parameters
IndexedArray(
index::INDEX,
content::CONTENT;
parameters::Parameters = Parameters(),
behavior::Symbol = :default,
) where {INDEX<:IndexBig,CONTENT<:Content} =
new{INDEX,CONTENT,behavior}(index, content, parameters)
end

IndexedArray{INDEX,CONTENT}(;
parameters::Parameters = Parameters(),
behavior::Symbol = :default,
) where {INDEX<:IndexBig} where {CONTENT<:Content} =
IndexedArray(INDEX([]), CONTENT(), parameters = parameters, behavior = behavior)

function copy(
layout::IndexedArray{INDEX1,CONTENT1,BEHAVIOR};
index::Union{Unset,INDEX2} = Unset(),
content::Union{Unset,CONTENT2} = Unset(),
parameters::Union{Unset,Parameters} = Unset(),
behavior::Union{Unset,Symbol} = Unset(),
) where {INDEX1<:IndexBig,INDEX2<:IndexBig,CONTENT1<:Content,CONTENT2<:Content,BEHAVIOR}
if isa(index, Unset)
index = layout.index
end
if isa(content, Unset)
content = layout.content
end
if isa(parameters, Unset)
parameters = parameters_of(layout)
end
if isa(behavior, Unset)
behavior = typeof(layout).parameters[end]
end
IndexedArray(index, content, parameters = parameters, behavior = behavior)
end

function is_valid(layout::IndexedArray)
for i in eachindex(layout.index)
if layout.index[i] >= length(layout.content)
return false
end
end
return is_valid(layout.content)
end

Base.length(layout::IndexedArray) = length(layout.index)
Base.firstindex(layout::IndexedArray) = firstindex(layout.index)
Base.lastindex(layout::IndexedArray) = lastindex(layout.index)

Base.getindex(layout::IndexedArray, i::Int) =
layout.content[layout.index[i]+firstindex(layout.content)]

Base.getindex(layout::IndexedArray, r::UnitRange{Int}) =
copy(layout, index = layout.index[r.start:r.stop])

Base.getindex(layout::IndexedArray, f::Symbol) = copy(layout, content = layout.content[f])

function push!(
layout::IndexedArray{INDEX,CONTENT},
x::ITEM,
) where {INDEX<:IndexBig,ITEM,CONTENT<:PrimitiveArray{ITEM}}
tmp = length(layout.content)
push!(layout.content, x)
Base.push!(layout.index, tmp)
layout
end

function end_list!(
layout::IndexedArray{INDEX,CONTENT},
) where {INDEX<:IndexBig,CONTENT<:ListType}
tmp = length(layout.content)
end_list!(layout.content)
Base.push!(layout.index, tmp)
layout
end

function end_record!(
layout::IndexedArray{INDEX,CONTENT},
) where {INDEX<:IndexBig,CONTENT<:RecordArray}
tmp = length(layout.content)
end_record!(layout.content)
Base.push!(layout.index, tmp)
layout
end

end
86 changes: 86 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -760,4 +760,90 @@ using Test
@test layout_2 == AwkwardArray.copy(layout_3, length = 2)
end

### IndexedArray #########################################################

begin
layout = AwkwardArray.IndexedArray(
[4, 3, 3, 0],
AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
)
@test length(layout) == 4
@test layout[1] == 5.5
@test layout[2] == 4.4
@test layout[3] == 4.4
@test layout[4] == 1.1
@test layout[2:4] == AwkwardArray.PrimitiveArray([4.4, 4.4, 1.1])
tmp = 0.0
for x in layout
@test x < 6
tmp += x
end
@test tmp == 15.4

AwkwardArray.push!(layout, 6.6)
@test length(layout) == 5
@test layout[5] == 6.6

AwkwardArray.push!(layout, 7.7)
@test length(layout) == 6
@test layout[6] == 7.7
@test layout.index == [4, 3, 3, 0, 5, 6]
@test layout == AwkwardArray.PrimitiveArray([5.5, 4.4, 4.4, 1.1, 6.6, 7.7])
end

begin
layout = AwkwardArray.IndexedArray(
[2, 0, 0, 1],
AwkwardArray.ListOffsetArray(
[0, 3, 3, 5],
AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
),
)
@test length(layout) == 4
@test layout[1] == AwkwardArray.PrimitiveArray([4.4, 5.5])
@test layout[2] == AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3])
@test layout[3] == AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3])
@test layout[4] == AwkwardArray.PrimitiveArray([])

sublayout = layout.content.content
AwkwardArray.push!(sublayout, 6.6)
AwkwardArray.push!(sublayout, 7.7)
AwkwardArray.end_list!(layout)
@test length(layout) == 5
@test layout[5] == AwkwardArray.PrimitiveArray([6.6, 7.7])
@test layout.index == [2, 0, 0, 1, 3]
end

begin
layout = AwkwardArray.IndexedArray(
[3, 4, 0, 0, 1, 2],
AwkwardArray.RecordArray(
NamedTuple{(:a, :b)}((
AwkwardArray.PrimitiveArray([1, 2, 3, 4, 5]),
AwkwardArray.PrimitiveArray([1.1, 2.2, 3.3, 4.4, 5.5]),
)),
),
)
@test length(layout) == 6
@test layout[1][:a] == 4
@test layout[1][:b] == 4.4
@test layout[end][:a] == 3
@test layout[end][:b] == 3.3
@test layout[:a][1] == 4
@test layout[:b][1] == 4.4
@test layout[:a][end] == 3
@test layout[:b][end] == 3.3

a_layout = layout.content.contents[:a]
b_layout = layout.content.contents[:b]

AwkwardArray.push!(a_layout, 6)
AwkwardArray.push!(b_layout, 6.6)
AwkwardArray.end_record!(layout)
@test length(layout) == 7
@test layout[end][:a] == 6
@test layout[end][:b] == 6.6
@test layout.index == [3, 4, 0, 0, 1, 2, 5]
end

end

0 comments on commit 8087ee3

Please sign in to comment.