Skip to content

reorganize slightly and add FixedSizeBitArray #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/FixedSizeArrays.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module FixedSizeArrays

include("FixedSizeArray.jl")
include("FixedSizeBitArray.jl")

if isdefined(Base, :dataids) && (Base.dataids isa Function)
# This is an internal, non-public function which is nevertheless needed to
Expand Down
78 changes: 78 additions & 0 deletions src/FixedSizeBitArray.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#unlike Base.BitArray, each column gets it's own chunk.
function num_bit_chunks(size::NTuple{N,Int}) where {N}
prod(size[1:end-1]) * ((size[end]+63) >> 6)

Check warning on line 3 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L2-L3

Added lines #L2 - L3 were not covered by tests
end

struct FixedSizeBitArray{N} <: AbstractArray{Bool,N}
chunks::Memory{UInt64}
size::NTuple{N,Int}

function FixedSizeBitArray{N}(::Internal, size::NTuple{N,Int}) where {N}
nc = num_bit_chunks(size)
chunks = Memory{UInt64}(undef, nc)

Check warning on line 12 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L10-L12

Added lines #L10 - L12 were not covered by tests
# we want the last chunks to be zeroed and it's easier to just zero all of them
copyto!(chunks, UInt64(0))
new{N}(chunks, size)

Check warning on line 15 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L14-L15

Added lines #L14 - L15 were not covered by tests
end
end

const FixedSizeBitVector = FixedSizeBitArray{1}
const FixedSizeBitMatrix = FixedSizeBitArray{2}


function FixedSizeBitArray{N}(::UndefInitializer, size::NTuple{N,Int}) where {N}
checked_dims(size)
FixedSizeBitArray{N}(Internal(), size)

Check warning on line 25 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L23-L25

Added lines #L23 - L25 were not covered by tests
end
function FixedSizeBitArray{N}(::UndefInitializer, size::NTuple{N,Integer}) where {N}
size = map(Int, size)::NTuple{N,Int} # prevent infinite recursion
FixedSizeBitArray{N}(undef, size)

Check warning on line 29 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L27-L29

Added lines #L27 - L29 were not covered by tests
end
function FixedSizeBitArray{N}(::UndefInitializer, size::Vararg{Integer,N}) where {N}
FixedSizeBitArray{N}(undef, size)

Check warning on line 32 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L31-L32

Added lines #L31 - L32 were not covered by tests
end
function FixedSizeBitArray(::UndefInitializer, size::NTuple{N,Integer}) where {N}
FixedSizeBitArray{N}(undef, size)

Check warning on line 35 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L34-L35

Added lines #L34 - L35 were not covered by tests
end
function FixedSizeBitArray(::UndefInitializer, size::Vararg{Integer,N}) where {N}
FixedSizeBitArray{N}(undef, size)

Check warning on line 38 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L37-L38

Added lines #L37 - L38 were not covered by tests
end

Base.IndexStyle(::Type{<:FixedSizeBitArray}) = IndexCartesian()

Check warning on line 41 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L41

Added line #L41 was not covered by tests

function get_chunks_id(inds::NTuple{N,Int}) where {N}
prod(inds[1:end-1])+(inds[end] >> 6), inds[end] & 63

Check warning on line 44 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L43-L44

Added lines #L43 - L44 were not covered by tests
end

Base.@propagate_inbounds function Base.getindex(A::FixedSizeBitArray{N}, inds::Vararg{Int, N}) where {N}
@boundscheck checkbounds(A, inds...)
i1, i2 = get_chunks_id(inds)
u = UInt64(1) << i2
@inbounds r = (A.chunks[i1] & u) != 0
return r

Check warning on line 52 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L47-L52

Added lines #L47 - L52 were not covered by tests

end
Base.@propagate_inbounds Base.@assume_effects :noub_if_noinbounds function Base.setindex!(A::FixedSizeBitArray{N}, x, inds::Vararg{Int, N}) where {N}
@boundscheck checkbounds(A, inds...)
i1, i2 = get_chunks_id(inds)
u = UInt64(1) << i2
@inbounds begin
c = A.chunks[i1]
A.chunks[i1] = ifelse(x, c | u, c & ~u)

Check warning on line 61 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L55-L61

Added lines #L55 - L61 were not covered by tests
end
return A

Check warning on line 63 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L63

Added line #L63 was not covered by tests
end

Base.size(a::FixedSizeBitArray) = a.size
Base.isassigned(a::FixedSizeBitArray, i::Int) = 1 <= i <= length(a)
function Base.fill!(B::FixedSizeBitArray, x)
y = convert(Bool, x)::Bool
fill!(B.chunks, UInt64(0)-y)

Check warning on line 70 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L66-L70

Added lines #L66 - L70 were not covered by tests
# TODO zero partially filled chunks
return B

Check warning on line 72 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L72

Added line #L72 was not covered by tests
end

function Base.:(==)(A::FixedSizeBitArray, B::FixedSizeBitArray)
size(A) != size(B) && return false
return A.chunks == B.chunks

Check warning on line 77 in src/FixedSizeBitArray.jl

View check run for this annotation

Codecov / codecov/patch

src/FixedSizeBitArray.jl#L75-L77

Added lines #L75 - L77 were not covered by tests
end
Loading