Skip to content

Commit

Permalink
Breaking: Remove support for types not in v3 Core (#40)
Browse files Browse the repository at this point in the history
* Remove support for non v3 types

* fix test deps
  • Loading branch information
nhz2 authored Oct 16, 2023
1 parent e05dfda commit 625b050
Show file tree
Hide file tree
Showing 17 changed files with 15 additions and 825 deletions.
5 changes: 1 addition & 4 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,18 @@ Blosc_jll = "0b7ba130-8d10-5ba8-a3d6-c5182647fed9"
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
StaticStrings = "4db0a0c5-418a-4e1d-8806-cb305fe13294"
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
TranscodingStreams = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
ZipArchives = "49080126-0e18-4c2a-b176-c102e4b3760c"

[compat]
AbstractTrees = "0.4"
ArgCheck = "2"
Base64 = "1.8"
Blosc_jll = "1.21"
CodecZlib = "0.7"
DataStructures = "0.18"
JSON3 = "1"
StaticArraysCore = "1"
StaticStrings = "0.2"
StructArrays = "0.6"
TranscodingStreams = "0.9, 0.10"
ZipArchives = "0.3, 0.4, 0.5, 1"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In memory hierarchy of arrays and attributes loaded from disk or to be saved to
1. If you need to store huge datasets that cannot fit uncompressed in memory consider using https://github.com/JuliaIO/HDF5.jl or https://github.com/JuliaIO/Zarr.jl

1. If you just want to serialize arbitrary Julia data consider using https://github.com/JuliaIO/JLD2.jl or https://github.com/invenia/JLSO.jl
2. Numpy datetime64 (“M”) and timedelta64 (“m”) data types are read as Int64.
2. Only Numpy types "b i u f c V" are supported.
3. Zarr filters are not supported.

## Overview
Expand Down
2 changes: 0 additions & 2 deletions src/SmallZarrGroups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ export ZGroup
export attrs
export children

include("char-utf32.jl")

include("ZArray.jl")
include("ZGroup.jl")

Expand Down
12 changes: 2 additions & 10 deletions src/ZArray.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using StaticArraysCore
using StaticStrings


const DEFAULT_COMPRESSOR = JSON3.read("""{
"blocksize": 0,
Expand All @@ -26,22 +25,15 @@ const ZDataTypes = Union{
ComplexF16,
ComplexF32,
ComplexF64,
StaticString,
SVector{N, CharUTF32} where N,
NTuple{N, UInt8} where N,
}

function isvalidtype(T::Type)::Bool
isbitstype(T) && (
(T <: ZDataTypes) ||
(T <: NamedTuple) && all(_isvalidfieldtype, fieldtypes(T))
(T <: ZDataTypes)
)
end

function _isvalidfieldtype(T::Type)::Bool
isvalidtype(T) || (T <: SArray) && isvalidtype(eltype(T))
end

"""
Create a ZArray.
Expand Down
87 changes: 0 additions & 87 deletions src/char-utf32.jl

This file was deleted.

97 changes: 4 additions & 93 deletions src/zarr-meta-parsing.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Parse zarr array meta data descriptions.

using ArgCheck
using StaticArraysCore
using StaticStrings
import JSON3
import Base64

Expand Down Expand Up @@ -57,10 +55,8 @@ function parse_zarr_type(typestr::String; silence_warnings=false)::ParsedType
numthings = parse(Int,rstrip(!isdigit, typestr[3:end]))
units = lstrip(isdigit, typestr[3:end])[begin+1:end-1]
@argcheck byteorder in "<>|"
@argcheck typechar in "biufcmMSUV"
@argcheck typechar in "biufcV"
@argcheck numthings 0
@argcheck (typechar in "mM") isempty(units)
@argcheck units in ("","Y","M","W","D","h","m","s","ms","μs","us","ns","ps","fs","as")
# actual number of bytes
if typechar == 'b'
@argcheck numthings == 1
Expand Down Expand Up @@ -118,108 +114,23 @@ function parse_zarr_type(typestr::String; silence_warnings=false)::ParsedType
byteorder = in_native_order ? (1:numthings) : [numthings÷2:-1:1; numthings:-1:numthings÷2+1;],
alignment = ALIGNMENT_LOOKUP[tz],
)
elseif (typechar == 'm') | (typechar == 'M')
@argcheck byteorder in "<>"
@argcheck numthings == 8
silence_warnings || @warn "timedelta64 and datatime64 not supported, converting to Int64"
in_native_order = (byteorder == NATIVE_ORDER)
tz = trailing_zeros(numthings)
return ParsedType(;
julia_type = Int64,
julia_size = 8,
byteorder = in_native_order ? (1:8) : (8:-1:1),
alignment = ALIGNMENT_LOOKUP[4],
)
elseif typechar == 'S'
return ParsedType(;
julia_type = StaticString{numthings},
julia_size = numthings,
byteorder = 1:numthings,
alignment = 0,
)
elseif typechar == 'U'
@argcheck (byteorder in "<>") || iszero(numthings)
in_native_order = (byteorder == NATIVE_ORDER) || iszero(numthings)
_byteorder = if in_native_order
collect(1:numthings*4)
else
collect(Iterators.flatten((4+4i,3+4i,2+4i,1+4i) for i in 0:numthings-1))
end
return ParsedType(;
julia_type = SVector{numthings, CharUTF32},
julia_size = numthings*4,
byteorder = _byteorder,
alignment = iszero(numthings) ? 0 : 2,
)
elseif typechar == 'V'
return ParsedType(;
julia_type = NTuple{numthings, UInt8},
julia_size = numthings,
byteorder = 1:numthings,
alignment = 0,
)
else
error("Unreachable")
end
end

"""
Parse a structured zarr typestr
"""
function parse_zarr_type(descr::JSON3.Array; silence_warnings=false)::ParsedType
current_byte = 0
max_alignment = 0
byteorder = Int[]
feldnames = Symbol[]
feldtypes = Type[]
for feld in descr
name::String = feld[1]
parsed_type::ParsedType = if length(feld) == 3
# Parse static array field.
@argcheck feld[3] isa JSON3.Array
shape::Vector{Int} = collect(Int,feld[3])
el_type = parse_zarr_type(feld[2]; silence_warnings)
el_size = el_type.julia_size
zarr_el_size = el_type.zarr_size
array_byteorder = Vector{Int}(undef, el_type.zarr_size*prod(shape))
# This thing converts a row major linear index to a column major index.
# This is needed because numpy static arrays are always in row major order
# and Julia static arrays are always in column major order.
converter_thing = PermutedDimsArray(LinearIndices(Tuple(shape)),reverse(1:length(shape)))
for i in 1:length(converter_thing)
column_major_idx_0::Int = converter_thing[i] - 1
local byte_offset::Int = column_major_idx_0*el_size
array_byteorder[(1+zarr_el_size*(i-1)):(zarr_el_size*i)] .= el_type.byteorder .+ byte_offset
end
ParsedType(;
julia_type = SArray{Tuple{shape...,}, el_type.julia_type, length(shape), prod(shape)},
julia_size = el_size*prod(shape),
zarr_size = length(byteorder),
byteorder = array_byteorder,
alignment = el_type.alignment,
)
elseif length(feld) == 2
parse_zarr_type(feld[2]; silence_warnings)
else
error("field must have 2 or three elements")
end
push!(feldnames, Symbol(name))
push!(feldtypes, parsed_type.julia_type)
alignment = parsed_type.alignment
max_alignment = max(max_alignment, alignment)
num_padding = 2^alignment - mod1(current_byte,2^alignment)
current_byte += num_padding
@assert iszero(mod(current_byte, 2^alignment))
append!(byteorder, parsed_type.byteorder .+ current_byte)
current_byte += parsed_type.julia_size
end
num_padding = 2^max_alignment - mod1(current_byte,2^max_alignment)
current_byte += num_padding
ParsedType(;
julia_type = NamedTuple{(feldnames...,), Tuple{feldtypes...,}},
julia_size = current_byte,
zarr_size = length(byteorder),
byteorder,
alignment = max_alignment,
)
error("Structured types not supported")
end


Expand Down
25 changes: 0 additions & 25 deletions src/zarr-meta-writing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,8 @@ function write_type(io::IO, t::Type)
print(io, "\"", NATIVE_ORDER, "c8\"")
elseif t <: ComplexF64
print(io, "\"", NATIVE_ORDER, "c16\"")
elseif t <: StaticString
print(io, "\"|S", sizeof(t), "\"")
elseif t <: (NTuple{N,UInt8} where N)
print(io, "\"|V", sizeof(t), "\"")
elseif t <: (SVector{N,CharUTF32} where N)
print(io, "\"", NATIVE_ORDER, "U", sizeof(t)>>2, "\"")
elseif t <: NamedTuple
print(io, "[")
need_comma = false
for (fname, ftype) in zip(fieldnames(t), fieldtypes(t))
if need_comma
print(io, ", ")
end
print(io, "[\"", fname, "\", ")
if (ftype <: SArray) && !(eltype(ftype) <: CharUTF32)
write_type(io, eltype(ftype))
print(io, ", [")
join(io, size(ftype), ", ")
print(io, "]")
else
write_type(io, ftype)
end
print(io, "]")
need_comma = true
end
print(io, "]")

else
error("type $t cannot be saved in a zarr array")
end
Expand Down
6 changes: 3 additions & 3 deletions test/Artifacts.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[fixture]
git-tree-sha1 = "487f11e78ae48112d036c7b146c767e7753b37e6"
git-tree-sha1 = "326a434121863402506a04ef77d42b049ccbcd1a"

[[fixture.download]]
sha256 = "4f0cccaaaa303fb876a7c5c3d6005f18cceeec7e73fb90a846600be72e020ed4"
url = "https://github.com/medyan-dev/SmallZarrGroups.jl/releases/download/v0.6.6/fixture.tar.gz"
sha256 = "59bbccec99379cdd4b4e6c7aba4e15cac146138d0c291fc4127955868ce3c934"
url = "https://github.com/medyan-dev/SmallZarrGroups.jl/releases/download/v0.6.6/fixture2.tar.gz"
5 changes: 3 additions & 2 deletions test/Fixture-README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ Add the file to the "fixture" directory, and a description to this file.
Then run
```julia
# This is the url that the artifact will be available from:
url_to_upload_to = "https://github.com/medyan-dev/SmallZarrGroups.jl/releases/download/v0.6.6/fixture.tar.gz"
tar_name = "fixture2.tar.gz"
url_to_upload_to = "https://github.com/medyan-dev/SmallZarrGroups.jl/releases/download/v0.6.6/"*tar_name
# This is the path to the Artifacts.toml we will manipulate
artifact_toml = "Artifacts.toml"
fixture_hash = create_artifact() do artifact_dir
cp(fixture_dir, artifact_dir; force=true)
end
tar_hash = archive_artifact(fixture_hash, "fixture.tar.gz")
tar_hash = archive_artifact(fixture_hash, tar_name)
bind_artifact!(artifact_toml, "fixture", fixture_hash; force=true,
download_info = [(url_to_upload_to, tar_hash)]
)
Expand Down
1 change: 0 additions & 1 deletion test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SmallZarrGroups = "d423b6e5-1c84-4ae2-8d2d-b903aee15ac7"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StaticStrings = "4db0a0c5-418a-4e1d-8806-cb305fe13294"
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1 change: 0 additions & 1 deletion test/experimental/test_chunking.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using SmallZarrGroups
using DataStructures: SortedDict, OrderedDict
using StaticArrays
using Test

#These are tests for experimental features that are not stable API yet
Expand Down
1 change: 0 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ using Random

Random.seed!(1234)

include("test_char-utf32.jl")
include("test_zarr-meta-parsing.jl")
include("test_zarr-meta-writing.jl")
include("test_simple-usage.jl")
Expand Down
Loading

2 comments on commit 625b050

@nhz2
Copy link
Member Author

@nhz2 nhz2 commented on 625b050 Oct 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/93462

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.7.0 -m "<description of version>" 625b0506a538061c84e5d4cdabbbac0c5c326f5a
git push origin v0.7.0

Please sign in to comment.