Skip to content

Commit

Permalink
feat: 'push_dummy' function, needed for some 'push_null' implementati…
Browse files Browse the repository at this point in the history
…ons. (#17)
  • Loading branch information
jpivarski authored Aug 28, 2023
1 parent fd5113f commit 27f58e3
Show file tree
Hide file tree
Showing 2 changed files with 336 additions and 81 deletions.
204 changes: 133 additions & 71 deletions src/AwkwardArray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,23 @@ Base.getindex(layout::PrimitiveArray, i::Int) = layout.data[i]
Base.getindex(layout::PrimitiveArray, r::UnitRange{Int}) =
copy(layout, data = layout.data[r])

Base.:(==)(layout1::PrimitiveArray, layout2::PrimitiveArray) = layout1.data == layout2.data # override for performance
function Base.:(==)(layout1::PrimitiveArray, layout2::PrimitiveArray)
if length(layout1) == 0 && length(layout2) == 0
true
else
layout1.data == layout2.data
end
end

function push!(layout::PrimitiveArray{ITEM}, x::ITEM) where {ITEM}
Base.push!(layout.data, x)
layout
end

function push_dummy!(layout::PrimitiveArray{ITEM}) where {ITEM}
push!(layout, zero(ITEM))
end

### EmptyArray ###########################################################

struct EmptyArray{BEHAVIOR} <: LeafType{BEHAVIOR}
Expand Down Expand Up @@ -309,6 +319,10 @@ function end_list!(layout::ListOffsetArray)
layout
end

function push_dummy!(layout::ListOffsetArray)
end_list!(layout)
end

### ListArray ############################################################

struct ListArray{INDEX<:IndexBig,CONTENT<:Content,BEHAVIOR} <: ListType{BEHAVIOR}
Expand Down Expand Up @@ -406,6 +420,10 @@ function end_list!(layout::ListArray)
Base.push!(layout.stops, length(layout.content))
end

function push_dummy!(layout::ListArray)
end_list!(layout)
end

### RegularArray #########################################################

mutable struct RegularArray{CONTENT<:Content,BEHAVIOR} <: ListType{BEHAVIOR}
Expand All @@ -426,12 +444,24 @@ mutable struct RegularArray{CONTENT<:Content,BEHAVIOR} <: ListType{BEHAVIOR}
end, parameters)
end

RegularArray{CONTENT}(
size::Int64;
parameters::Parameters = Parameters(),
behavior::Symbol = :default,
) where {CONTENT<:Content} = RegularArray(
CONTENT(),
size,
zeros_length = 0,
parameters = parameters,
behavior = behavior,
)

RegularArray{CONTENT}(;
parameters::Parameters = Parameters(),
behavior::Symbol = :default,
) where {CONTENT<:Content} = RegularArray(
CONTENT(),
0,
-1,
zeros_length = 0,
parameters = parameters,
behavior = behavior,
Expand Down Expand Up @@ -481,21 +511,23 @@ Base.firstindex(layout::RegularArray) = 1
Base.lastindex(layout::RegularArray) = length(layout)

function Base.getindex(layout::RegularArray, i::Int)
start = (i - firstindex(layout)) * layout.size + firstindex(layout.content)
stop = (i + 1 - firstindex(layout)) * layout.size + firstindex(layout.content) - 1
size = max(0, layout.size)
start = (i - firstindex(layout)) * size + firstindex(layout.content)
stop = (i + 1 - firstindex(layout)) * size + firstindex(layout.content) - 1
layout.content[start:stop]
end

function Base.getindex(layout::RegularArray, r::UnitRange{Int})
start = (r.start - firstindex(layout)) * layout.size + firstindex(layout.content)
stop = (r.stop - 1 - firstindex(layout)) * layout.size + firstindex(layout.content) + 1
size = max(0, layout.size)
start = (r.start - firstindex(layout)) * size + firstindex(layout.content)
stop = (r.stop - 1 - firstindex(layout)) * size + firstindex(layout.content) + 1
copy(layout, content = layout.content[start:stop], zeros_length = r.stop - r.start + 1)
end

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

function end_list!(layout::RegularArray)
if layout.length == 0
if layout.size < 0 && layout.length == 0
layout.size = length(layout.content)
layout.length = 1
elseif length(layout.content) == (layout.length + 1) * layout.size
Expand All @@ -507,6 +539,13 @@ function end_list!(layout::RegularArray)
end
end

function push_dummy!(layout::RegularArray)
for _ = 1:max(0, layout.size)
push_dummy!(layout.content)
end
end_list!(layout)
end

### ListType with behavior = :string #####################################

function Base.getindex(
Expand Down Expand Up @@ -699,16 +738,21 @@ function Base.getindex(layout::RecordArray, f::Symbol)
content[firstindex(content):firstindex(content)+length(layout)-1]
end

slot(layout::RecordArray, f::Symbol) = layout[f] # synonym; necessary for TupleArray

Base.getindex(layout::Record, f::Symbol) = layout.array.contents[f][layout.at]

function Base.:(==)(
layout1::RecordArray{CONTENTS},
layout2::RecordArray{CONTENTS},
) where {CONTENTS<:NamedTuple}
layout1::RecordArray{CONTENTS1},
layout2::RecordArray{CONTENTS2},
) where {CONTENTS1<:NamedTuple,CONTENTS2<:NamedTuple}
if length(layout1) != length(layout2)
return false
end
for k in keys(layout1.contents) # same keys because same CONTENTS type
if keys(layout1) != keys(layout2)
return false
end
for k in keys(layout1.contents)
if layout1[k] != layout2[k] # compare whole arrays
return false
end
Expand All @@ -717,11 +761,19 @@ function Base.:(==)(
end

function Base.:(==)(
layout1::Record{ARRAY},
layout2::Record{ARRAY},
) where {CONTENTS<:NamedTuple,ARRAY<:RecordArray{CONTENTS}}
for k in keys(layout1.array.contents) # same keys because same CONTENTS type
if layout1[k] != layout2[k] # compare record items
layout1::Record{ARRAY1},
layout2::Record{ARRAY2},
) where {
CONTENTS1<:NamedTuple,
CONTENTS2<:NamedTuple,
ARRAY1<:RecordArray{CONTENTS1},
ARRAY2<:RecordArray{CONTENTS2},
}
if keys(layout1.array.contents) != keys(layout2.array.contents)
return false
end
for k in keys(layout1.array.contents)
if layout1[k] != layout2[k] # compare record items
return false
end
end
Expand All @@ -734,6 +786,13 @@ function end_record!(layout::RecordArray)
layout
end

function push_dummy!(layout::RecordArray)
for x in layout.contents
push_dummy!(x)
end
end_record!(layout)
end

### TupleArray ###########################################################

mutable struct TupleArray{CONTENTS<:Base.Tuple,BEHAVIOR} <: Content{BEHAVIOR}
Expand Down Expand Up @@ -831,12 +890,15 @@ end
Base.getindex(layout::Tuple, f::Int64) = layout.array.contents[f][layout.at]

function Base.:(==)(
layout1::TupleArray{CONTENTS},
layout2::TupleArray{CONTENTS},
) where {CONTENTS<:Base.Tuple}
layout1::TupleArray{CONTENTS1},
layout2::TupleArray{CONTENTS2},
) where {CONTENTS1<:Base.Tuple,CONTENTS2<:Base.Tuple}
if length(layout1) != length(layout2)
return false
end
if length(layout1.contents) != length(layout2.contents)
return false
end
for i in eachindex(layout1.contents) # same indexes because same CONTENTS type
if slot(layout1, i) != slot(layout2, i) # compare whole arrays
return false
Expand All @@ -846,9 +908,17 @@ function Base.:(==)(
end

function Base.:(==)(
layout1::Tuple{ARRAY},
layout2::Tuple{ARRAY},
) where {CONTENTS<:Base.Tuple,ARRAY<:TupleArray{CONTENTS}}
layout1::Tuple{ARRAY1},
layout2::Tuple{ARRAY2},
) where {
CONTENTS1<:Base.Tuple,
CONTENTS2<:Base.Tuple,
ARRAY1<:TupleArray{CONTENTS1},
ARRAY2<:TupleArray{CONTENTS2},
}
if length(layout1.array.contents) != length(layout2.array.contents)
return false
end
for i in eachindex(layout1.array.contents) # same indexes because same CONTENTS type
if layout1[i] != layout2[i] # compare tuple items
return false
Expand All @@ -863,6 +933,13 @@ function end_tuple!(layout::TupleArray)
layout
end

function push_dummy!(layout::TupleArray)
for x in layout.contents
push_dummy!(x)
end
end_tuple!(layout)
end

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

struct IndexedArray{INDEX<:IndexBig,CONTENT<:Content,BEHAVIOR} <: Content{BEHAVIOR}
Expand Down Expand Up @@ -937,9 +1014,7 @@ function push!(
layout
end

function end_list!(
layout::IndexedArray{INDEX,CONTENT},
) where {INDEX<:IndexBig,CONTENT<:ListType}
function end_list!(layout::IndexedArray)
tmp = length(layout.content)
end_list!(layout.content)
Base.push!(layout.index, tmp)
Expand All @@ -960,6 +1035,13 @@ function end_tuple!(layout::IndexedArray)
layout
end

function push_dummy!(layout::IndexedArray)
tmp = length(layout.content)
push_dummy!(layout.content)
Base.push!(layout.index, tmp)
layout
end

### IndexedOptionArray ###################################################

abstract type OptionType{BEHAVIOR} <: Content{BEHAVIOR} end
Expand Down Expand Up @@ -1068,6 +1150,10 @@ function push_null!(layout::IndexedOptionArray)
layout
end

function push_dummy!(layout::IndexedOptionArray)
push_null!(layout)
end

### ByteMaskedArray ######################################################

struct ByteMaskedArray{INDEX<:IndexBool,CONTENT<:Content,BEHAVIOR} <: OptionType{BEHAVIOR}
Expand Down Expand Up @@ -1188,36 +1274,14 @@ function end_tuple!(layout::ByteMaskedArray)
layout
end

function push_null!(
layout::ByteMaskedArray{INDEX,CONTENT},
) where {INDEX<:IndexBool,ITEM,CONTENT<:PrimitiveArray{ITEM}}
push!(layout.content, zero(ITEM))
function push_null!(layout::ByteMaskedArray)
push_dummy!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
end

function push_null!(
layout::ByteMaskedArray{INDEX,CONTENT},
) where {INDEX<:IndexBool,CONTENT<:ListType}
end_list!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
end

function push_null!(
layout::ByteMaskedArray{INDEX,CONTENT},
) where {INDEX<:IndexBool,CONTENT<:RecordArray}
end_record!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
end

function push_null!(
layout::ByteMaskedArray{INDEX,CONTENT},
) where {INDEX<:IndexBool,CONTENT<:TupleArray}
end_tuple!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
function push_dummy!(layout::ByteMaskedArray)
push_null!(layout)
end

### BitMaskedArray #######################################################
Expand Down Expand Up @@ -1341,30 +1405,14 @@ function end_tuple!(layout::BitMaskedArray)
layout
end

function push_null!(
layout::BitMaskedArray{CONTENT},
) where {ITEM,CONTENT<:PrimitiveArray{ITEM}}
push!(layout.content, zero(ITEM))
Base.push!(layout.mask, !layout.valid_when)
layout
end

function push_null!(layout::BitMaskedArray{CONTENT}) where {CONTENT<:ListType}
end_list!(layout.content)
function push_null!(layout::BitMaskedArray)
push_dummy!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
end

function push_null!(layout::BitMaskedArray{CONTENT}) where {CONTENT<:RecordArray}
end_record!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
end

function push_null!(layout::BitMaskedArray{CONTENT}) where {CONTENT<:TupleArray}
end_tuple!(layout.content)
Base.push!(layout.mask, !layout.valid_when)
layout
function push_dummy!(layout::BitMaskedArray)
push_null!(layout)
end

### UnmaskedArray ########################################################
Expand Down Expand Up @@ -1442,6 +1490,10 @@ function end_tuple!(layout::UnmaskedArray)
layout
end

function push_dummy!(layout::UnmaskedArray)
push_dummy!(layout.content)
end

### UnionArray ###########################################################

struct UnionArray{TAGS<:Index8,INDEX<:IndexBig,CONTENTS<:Base.Tuple,BEHAVIOR} <:
Expand Down Expand Up @@ -1631,4 +1683,14 @@ function push_null!(
special
end

function push_dummy!(
special::Specialization{ARRAY,TAGGED},
) where {ARRAY<:UnionArray,TAGGED<:Content}
tmp = length(special.tagged)
push_dummy!(special.tagged)
Base.push!(special.array.tags, special.tag - firstindex(special.array.contents))
Base.push!(special.array.index, tmp)
special
end

end # module AwkwardArray
Loading

0 comments on commit 27f58e3

Please sign in to comment.