Skip to content
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 groups lazily #157

Open
wants to merge 2 commits into
base: master
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
62 changes: 27 additions & 35 deletions src/ZGroup.jl
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
struct ZGroup{S<:AbstractStore}
storage::S
path::String
arrays::Dict{String, ZArray}
groups::Dict{String, ZGroup}
attrs::Dict
writeable::Bool
fill_as_missing::Bool
end

# path can also be a SubString{String}
ZGroup(storage, path::AbstractString, arrays, groups, attrs, writeable) =
ZGroup(storage, String(path), arrays, groups, attrs, writeable)
ZGroup(storage, path::AbstractString, attrs, writeable, fill_as_missing) =
ZGroup(storage, String(path), attrs, writeable, fill_as_missing)

zname(g::ZGroup) = zname(g.path)

#Open an existing ZGroup
function ZGroup(s::T,mode="r",path="";fill_as_missing=false) where T <: AbstractStore
arrays = Dict{String, ZArray}()
groups = Dict{String, ZGroup}()

for d in subdirs(s,path)
dshort = split(d,'/')[end]
m = zopen_noerr(s,mode,path=_concatpath(path,dshort),fill_as_missing=fill_as_missing)
if isa(m, ZArray)
arrays[dshort] = m
elseif isa(m, ZGroup)
groups[dshort] = m
end
end
attrs = getattrs(s,path)
startswith(path,"/") && error("Paths should never start with a leading '/'")
ZGroup(s, path, arrays, groups, attrs,mode=="w")
attrs = getattrs(s,path)
startswith(path,"/") && error("Paths should never start with a leading '/'")
ZGroup(s, path, attrs, mode == "w", fill_as_missing)
end

"""
Expand Down Expand Up @@ -59,21 +46,28 @@

function Base.show(io::IO, g::ZGroup)
print(io, "ZarrGroup at ", g.storage, " and path ", g.path)
!isempty(g.arrays) && print(io, "\nVariables: ", map(i -> string(zname(i), " "), values(g.arrays))...)
!isempty(g.groups) && print(io, "\nGroups: ", map(i -> string(zname(i), " "), values(g.groups))...)
nothing
for (i, d) in enumerate(subdirs(g.storage, g.path))
if i > 10 # don't print too many
print(io, "\n ...")
break

Check warning on line 52 in src/ZGroup.jl

View check run for this annotation

Codecov / codecov/patch

src/ZGroup.jl#L49-L52

Added lines #L49 - L52 were not covered by tests
end
path = _concatpath(g.path, d)
if is_zarray(g.storage, path)
print(io, "\n ", d, " (Array)")
elseif is_zgroup(g.storage, path)
print(io, "\n ", d, " (Group)")

Check warning on line 58 in src/ZGroup.jl

View check run for this annotation

Codecov / codecov/patch

src/ZGroup.jl#L54-L58

Added lines #L54 - L58 were not covered by tests
end
end

Check warning on line 60 in src/ZGroup.jl

View check run for this annotation

Codecov / codecov/patch

src/ZGroup.jl#L60

Added line #L60 was not covered by tests
end
Base.haskey(g::ZGroup,k)= haskey(g.groups,k) || haskey(g.arrays,k)

function Base.haskey(g::ZGroup, k)
path = _concatpath(g.path, k)
is_zarray(g.storage, path) || is_zgroup(g.storage, path)

Check warning on line 65 in src/ZGroup.jl

View check run for this annotation

Codecov / codecov/patch

src/ZGroup.jl#L63-L65

Added lines #L63 - L65 were not covered by tests
end

function Base.getindex(g::ZGroup, k)
if haskey(g.groups, k)
return g.groups[k]
elseif haskey(g.arrays, k)
return g.arrays[k]
else
throw(KeyError("Zarr Dataset does not contain $k"))
end
m = zopen_noerr(g.storage, g.writeable ? "w" : "r", path = _concatpath(g.path, k), fill_as_missing = g.fill_as_missing)
m !== nothing ? m : throw(KeyError(k))
end

"""
Expand Down Expand Up @@ -135,24 +129,22 @@
JSON.print(b,d)
s[path,".zgroup"]=take!(b)
writeattrs(s,path,attrs)
ZGroup(s, path, Dict{String,ZArray}(), Dict{String,ZGroup}(), attrs,true)
ZGroup(s, path, attrs, true, false)
end

zgroup(s::String;kwargs...)=zgroup(storefromstring(s, true)...;kwargs...)

"Create a subgroup of the group g"
function zgroup(g::ZGroup, name; attrs=Dict())
g.writeable || throw(IOError("Zarr group is not writeable. Please re-open in write mode to create an array"))
g.groups[name] = zgroup(g.storage,_concatpath(g.path,name),attrs=attrs)
zgroup(g.storage, _concatpath(g.path, name), attrs = attrs)
end

"Create a new subarray of the group g"
function zcreate(::Type{T},g::ZGroup, name::AbstractString, addargs...; kwargs...) where T
g.writeable || throw(IOError("Zarr group is not writeable. Please re-open in write mode to create an array"))
name = string(name)
z = zcreate(T, g.storage, addargs...; path = _concatpath(g.path,name), kwargs...)
g.arrays[name] = z
return z
zcreate(T, g.storage, addargs...; path = _concatpath(g.path, name), kwargs...)
end

HTTP.serve(s::Union{ZArray,ZGroup}, args...; kwargs...) = HTTP.serve(s.storage, s.path, args...; kwargs...)
Expand Down
2 changes: 1 addition & 1 deletion test/storage.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ end
@test storagesize(S3,p) == 0
@test Zarr.is_zgroup(S3,p) == true
S3group = zopen(S3,path=p)
S3Array = S3group.groups["bar"].arrays["baz"]
S3Array = S3group["bar"]["baz"]
@test eltype(S3Array) == Zarr.ASCIIChar
@test storagesize(S3Array) == 69
@test String(S3Array[:]) == "Hello from the cloud!"
Expand Down
Loading