diff --git a/src/datasets.jl b/src/datasets.jl index ce50cfa2..a71bd01b 100644 --- a/src/datasets.jl +++ b/src/datasets.jl @@ -367,7 +367,7 @@ end seek(io, header_offset) f.end_of_data = header_offset + fullsz - track!(wsession, data, header_offset) + track!(wsession, data, h5offset(f, header_offset)) cio = begin_checksum_write(io, fullsz - 4) jlwrite(cio, ObjectStart(size_flag(psz))) @@ -377,7 +377,7 @@ end for attr in dataspace.attributes write_header_message(cio, f, attr) end - write_header_message(cio, Val(HmDatatype), 1 | (2*isa(dt, CommittedDatatype)); dt) + write_header_message(cio, Val(HmDatatype), 1 | (2*isa(datatype, CommittedDatatype)); dt=datatype) # Data storage layout if layout_class == LcCompact diff --git a/src/explicit_datasets.jl b/src/explicit_datasets.jl index 7168f70e..8026953b 100644 --- a/src/explicit_datasets.jl +++ b/src/explicit_datasets.jl @@ -144,12 +144,17 @@ function write_dataset(dataset::Dataset, data, wsession::JLDWriteSession=JLDWrit end offset = write_dataset(f, dataspace, datatype, odr, data, wsession, compressor) !isempty(dataset.name) && (dataset.parent[dataset.name] = offset) - # Attributes - # TODO: this can be optimized by writing all attributes at once - for (name, attr) in pairs(dataset.attributes) - add_attribute(dataset, name, value, wsession) + attrs = map(collect(keys(pairs(dataset.attributes)))) do name + WrittenAttribute(f, name, dataset.attributes[name]) end + dataset = get_dataset(f, offset, dataset.parent, dataset.name) + dataset.header_chunk_info = + attach_message(f, dataset.offset, attrs, wsession; + chunk_start=dataset.header_chunk_info[1], + chunk_end=dataset.header_chunk_info[2], + next_msg_offset=dataset.header_chunk_info[3], + ) return offset end @@ -341,9 +346,9 @@ function add_attribute(dset::Dataset, name::String, data, wsession=JLDWriteSessi f = dset.parent.f prewrite(f) # assert writability - for attr in dset.attributes - if (attr isa ReadAttribute && attr.name == name) || (attr isa Pair && attr.first == name) - throw(ArgumentError("Attribute $name already exists. Attribute names must be unique.")) + for attrname in keys(dset.attributes) + if name == attrname + throw(ArgumentError("Attribute \"$name\" already exists. Attribute names must be unique.")) end end dset.attributes[name] = data @@ -484,7 +489,7 @@ function allocate_early(dset::Dataset, T::DataType) for attr in dataspace.attributes write_header_message(cio, f, attr) end - write_header_message(cio, Val(HmDatatype), 1 | (2*isa(dt, CommittedDatatype)); dt) + write_header_message(cio, Val(HmDatatype), 1 | (2*isa(datatype, CommittedDatatype)); dt=datatype) for a in attributes write_header_message(cio, f, a, wsession) end diff --git a/src/types.jl b/src/types.jl index aa98ed54..c9e7ad77 100644 --- a/src/types.jl +++ b/src/types.jl @@ -114,17 +114,14 @@ referenced multiple times are written multiple times. """ struct JLDWriteSession{T<:Union{Dict{UInt,RelOffset},Union{}}} h5offset::T - objects::Vector{Any} - JLDWriteSession{T}() where T = new() - JLDWriteSession{T}(h5offset, objects) where T = new(h5offset, objects) + JLDWriteSession{T}(h5offset, objects) where T = new(h5offset) end JLDWriteSession() = JLDWriteSession{Dict{UInt,RelOffset}}(Dict{UInt,RelOffset}(), Any[]) -track!(s::JLDWriteSession{Union{}}, args...) = nothing +track!(::JLDWriteSession{Union{}}, args...) = nothing function track!(s::JLDWriteSession, data, offset::RelOffset) if ismutabletype(typeof(data)) - wsession.h5offset[objectid(data)] = h5offset(f, header_offset) - push!(wsession.objects, data) + s.h5offset[objectid(data)] = offset end nothing end