Skip to content

Commit 62e9b24

Browse files
committed
Update JLD for JuliaLang/julia#10380
1 parent 0e816df commit 62e9b24

File tree

3 files changed

+90
-36
lines changed

3 files changed

+90
-36
lines changed

src/JLD.jl

+23-5
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ immutable AssociativeWrapper{K,V,T<:Associative}
111111
values::Vector{V}
112112
end
113113

114+
# Wrapper for SimpleVector
115+
immutable SimpleVectorWrapper
116+
elements::Vector
117+
end
118+
114119
include("jld_types.jl")
115120

116121
file(x::JldFile) = x
@@ -376,6 +381,11 @@ function after_read{K,V,T}(x::AssociativeWrapper{K,V,T})
376381
ret
377382
end
378383

384+
# Special case for SimpleVector
385+
if VERSION >= v"0.4.0-dev+4319"
386+
after_read(x::SimpleVectorWrapper) = Base.svec(x.elements...)
387+
end
388+
379389
## Arrays
380390

381391
# Read an array
@@ -488,7 +498,7 @@ write(parent::Union(JldFile, JldGroup), name::ByteString,
488498
close(_write(parent, name, data, wsession; kargs...))
489499

490500
# Pick whether to use compact or default storage based on data size
491-
function dset_create_properties(parent, sz::Int, obj, chunk=Int[]; mmap = false)
501+
function dset_create_properties(parent, sz::Int, obj, chunk=Int[]; mmap::Bool=false)
492502
if sz <= 8192 && !ismmapped(parent) && !mmap
493503
return compact_properties(), false
494504
end
@@ -634,18 +644,24 @@ write_ref(parent::JldGroup, data, wsession::JldWriteSession) =
634644
write_ref(file(parent), data, wsession)
635645

636646
# Special case for associative, to rehash keys
637-
function _write(parent::Union(JldFile, JldGroup), name::ByteString,
638-
d::Associative, wsession::JldWriteSession; kargs...)
647+
function _write{K,V}(parent::Union(JldFile, JldGroup), name::ByteString,
648+
d::Associative{K,V}, wsession::JldWriteSession; kargs...)
639649
n = length(d)
640-
K, V = eltype(d)
641650
ks = Array(K, n)
642651
vs = Array(V, n)
643652
i = 0
644653
for (k,v) in d
645654
ks[i+=1] = k
646655
vs[i] = v
647656
end
648-
write_compound(parent, name, AssociativeWrapper{K,V,typeof(d)}(ks, vs), wsession)
657+
write_compound(parent, name, AssociativeWrapper{K,V,typeof(d)}(ks, vs), wsession; kargs...)
658+
end
659+
660+
# Special case for SimpleVector
661+
if VERSION >= v"0.4.0-dev+4319"
662+
_write(parent::Union(JldFile, JldGroup), name::ByteString,
663+
d::SimpleVector, wsession::JldWriteSession; kargs...) =
664+
write_compound(parent, name, SimpleVectorWrapper([d...]), wsession; kargs...)
649665
end
650666

651667
# Expressions, drop line numbers
@@ -859,6 +875,8 @@ function full_typename(io::IO, file::JldFile, jltype::DataType)
859875
full_typename(io, file, jltype.parameters[i])
860876
end
861877
print(io, '}')
878+
elseif jltype <: Tuple
879+
print(io, "{}")
862880
end
863881
end
864882
function full_typename(file::JldFile, x)

src/jld_types.jl

+57-29
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@ const BUILTIN_TYPES = Set([Symbol, Type, UTF16String, BigFloat, BigInt])
1010
const H5CONVERT_DEFINED = ObjectIdDict()
1111
const JLCONVERT_DEFINED = ObjectIdDict()
1212

13+
if VERSION >= v"0.4.0-dev+4319"
14+
const EMPTY_TUPLE_TYPE = Tuple{}
15+
typealias TypesType SimpleVector
16+
typealias TupleType{T<:Tuple} Type{T}
17+
tupletypes(T::TupleType) = T.parameters
18+
typetuple(types) = Tuple{types...}
19+
else
20+
const EMPTY_TUPLE_TYPE = ()
21+
typealias TypesType (Type...)
22+
typealias TupleType (Type...)
23+
tupletypes(T::TupleType) = T
24+
typetuple(types) = tuple(types...)
25+
end
26+
1327
## Helper functions
1428

1529
# Holds information about the mapping between a Julia and HDF5 type
@@ -20,7 +34,7 @@ immutable JldTypeInfo
2034
end
2135

2236
# Get information about the HDF5 types corresponding to Julia types
23-
function JldTypeInfo(parent::JldFile, types::(@compat Tuple{Vararg{Type}}), commit::Bool)
37+
function JldTypeInfo(parent::JldFile, types::TypesType, commit::Bool)
2438
dtypes = Array(JldDatatype, length(types))
2539
offsets = Array(Int, length(types))
2640
offset = 0
@@ -257,7 +271,7 @@ function h5type{T<:Type}(parent::JldFile, ::Type{T}, commit::Bool)
257271
id = HDF5.h5t_create(HDF5.H5T_COMPOUND, 8)
258272
HDF5.h5t_insert(id, "typename_", 0, h5fieldtype(parent, UTF8String, commit))
259273
dtype = HDF5Datatype(id, parent.plain)
260-
commit ? commit_datatype(parent, dtype, Type) : JldDatatype(dtype, -1)
274+
out = commit ? commit_datatype(parent, dtype, Type) : JldDatatype(dtype, -1)
261275
end
262276

263277
gen_h5convert{T<:Type}(::JldFile, ::Type{T}) = nothing
@@ -292,16 +306,13 @@ h5fieldtype{T,N}(parent::JldFile, ::Type{Array{T,N}}, ::Bool) = JLD_REF_TYPE
292306
## Tuples
293307

294308
if INLINE_TUPLE
295-
h5fieldtype(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), commit::Bool) =
309+
h5fieldtype(parent::JldFile, T::TupleType, commit::Bool) =
296310
isleaftype(T) ? h5type(parent, T, commit) : JLD_REF_TYPE
297311
else
298-
h5fieldtype(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), ::Bool) = JLD_REF_TYPE
312+
h5fieldtype(parent::JldFile, T::TupleType, ::Bool) = JLD_REF_TYPE
299313
end
300314

301-
function h5type(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), commit::Bool)
302-
!isa(T, (@compat Tuple{Vararg{Union((@compat Tuple), DataType)}})) && unknown_type_err(T)
303-
T = T::(@compat Tuple{Vararg{Union((@compat Tuple), DataType)}})
304-
315+
function h5type(parent::JldFile, T::TupleType, commit::Bool)
305316
haskey(parent.jlh5type, T) && return parent.jlh5type[T]
306317
# Tuples should always be concretely typed, unless we're
307318
# reconstructing a tuple, in which case commit will be false
@@ -321,7 +332,7 @@ function h5type(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), commit::Bool)
321332
dtype = HDF5Datatype(id, parent.plain)
322333
if commit
323334
jlddtype = commit_datatype(parent, dtype, T)
324-
if isempty(T)
335+
if T == EMPTY_TUPLE_TYPE
325336
# to allow recovery of empty tuples, which HDF5 does not allow
326337
a_write(dtype, "empty", @compat UInt8(1))
327338
end
@@ -331,21 +342,22 @@ function h5type(parent::JldFile, T::(@compat Tuple{Vararg{Type}}), commit::Bool)
331342
end
332343
end
333344

334-
function gen_jlconvert(typeinfo::JldTypeInfo, T::(@compat Tuple{Vararg{Type}}))
345+
function gen_jlconvert(typeinfo::JldTypeInfo, T::TupleType)
335346
haskey(JLCONVERT_DEFINED, T) && return
336347

337348
ex = Expr(:block)
338349
args = ex.args
339350
tup = Expr(:tuple)
340351
tupargs = tup.args
352+
types = tupletypes(T)
341353
for i = 1:length(typeinfo.dtypes)
342354
h5offset = typeinfo.offsets[i]
343355
field = symbol(string("field", i))
344356

345357
if HDF5.h5t_get_class(typeinfo.dtypes[i]) == HDF5.H5T_REFERENCE
346358
push!(args, :($field = read_ref(file, unsafe_load(convert(Ptr{HDF5ReferenceObj}, ptr)+$h5offset))))
347359
else
348-
push!(args, :($field = jlconvert($(T[i]), file, ptr+$h5offset)))
360+
push!(args, :($field = jlconvert($(types[i]), file, ptr+$h5offset)))
349361
end
350362
push!(tupargs, field)
351363
end
@@ -434,7 +446,20 @@ function _gen_jlconvert_immutable(typeinfo::JldTypeInfo, T::ANY)
434446
h5offset = typeinfo.offsets[i]
435447
jloffset = jloffsets[i]
436448

437-
if HDF5.h5t_get_class(typeinfo.dtypes[i]) == HDF5.H5T_REFERENCE
449+
if isa(T.types[i], TupleType) && VERSION >= v"0.4.0-dev+4319" && T.types[i].pointerfree
450+
# We continue to store tuples as references for the sake of
451+
# backwards compatibility, but on 0.4 they are now stored
452+
# inline
453+
push!(args, quote
454+
ref = unsafe_load(convert(Ptr{HDF5ReferenceObj}, ptr)+$h5offset)
455+
if ref == HDF5.HDF5ReferenceObj_NULL
456+
warn("""A pointerfree tuple field was undefined.
457+
This is not supported in Julia 0.4 and the corresponding tuple will be uninitialized.""")
458+
else
459+
unsafe_store!(convert(Ptr{$(T.types[i])}, out)+$jloffset, read_ref(file, ref))
460+
end
461+
end)
462+
elseif HDF5.h5t_get_class(typeinfo.dtypes[i]) == HDF5.H5T_REFERENCE
438463
obj = gensym("obj")
439464
push!(args, quote
440465
ref = unsafe_load(convert(Ptr{HDF5ReferenceObj}, ptr)+$h5offset)
@@ -523,19 +548,20 @@ end
523548
## Common functions for all non-special types (including gen_h5convert)
524549

525550
# Whether this datatype should be stored as opaque
526-
isopaque(t::@compat Tuple{Vararg{Type}}) = isa(t, ())
527-
isopaque(t::DataType) = isempty(fieldnames(t))
551+
isopaque(t::TupleType) = t == EMPTY_TUPLE_TYPE
552+
# isopaque(t::DataType) = isempty(fieldnames(t))
553+
isopaque(t::DataType) = isa(t, TupleType) ? t == EMPTY_TUPLE_TYPE : isempty(fieldnames(t))
528554

529555
# The size of this datatype in the HDF5 file (if opaque)
530-
opaquesize(t::@compat Tuple{Vararg{DataType}}) = 1
556+
opaquesize(t::TupleType) = 1
531557
opaquesize(t::DataType) = max(1, t.size)
532558

533559
# Whether a type that is stored inline in HDF5 should be stored as a
534560
# reference in Julia. This will only be called such that it returns
535561
# true for some unions of special types defined above, unless either
536562
# INLINE_TUPLE or INLINE_POINTER_IMMUTABLE is true.
537563
uses_reference(T::DataType) = !T.pointerfree
538-
uses_reference(::@compat Tuple) = true
564+
uses_reference(::TupleType) = true
539565
uses_reference(::UnionType) = true
540566

541567
unknown_type_err(T) =
@@ -548,19 +574,21 @@ gen_h5convert(parent::JldFile, T) =
548574
# There is no point in specializing this
549575
function _gen_h5convert(parent::JldFile, T::ANY)
550576
dtype = parent.jlh5type[T].dtype
551-
istuple = isa(T, @compat Tuple)
577+
istuple = isa(T, TupleType)
578+
579+
if isopaque(T)
580+
if T.size == 0
581+
@eval h5convert!(out::Ptr, ::JldFile, x::$T, ::JldWriteSession) = nothing
582+
else
583+
@eval h5convert!(out::Ptr, ::JldFile, x::$T, ::JldWriteSession) =
584+
unsafe_store!(convert(Ptr{$T}, out), x)
585+
end
586+
return
587+
end
588+
552589
if istuple
553-
types = T
590+
types = tupletypes(T)
554591
else
555-
if isopaque(T::DataType)
556-
if (T::DataType).size == 0
557-
@eval h5convert!(out::Ptr, ::JldFile, x::$T, ::JldWriteSession) = nothing
558-
else
559-
@eval h5convert!(out::Ptr, ::JldFile, x::$T, ::JldWriteSession) =
560-
unsafe_store!(convert(Ptr{$T}, out), x)
561-
end
562-
return
563-
end
564592
types = (T::DataType).types
565593
end
566594

@@ -704,9 +732,9 @@ function reconstruct_type(parent::JldFile, dtype::HDF5Datatype, savedname::Abstr
704732
end
705733
end
706734

707-
if startswith(savedname, "(")
735+
if startswith(savedname, "(") || startswith(savedname, "Core.Tuple{")
708736
# We're reconstructing a tuple
709-
tuple(fieldtypes...)
737+
typetuple(fieldtypes)
710738
else
711739
# We're reconstructing some other type
712740
@eval begin

test/jld.jl

+10-2
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,19 @@ bitsparamint16 = BitsParams{@compat Int16(1)}()
205205
# Tuple of tuples
206206
tuple_of_tuples = (1, 2, (3, 4, [5, 6]), [7, 8])
207207

208+
# SimpleVector
209+
if VERSION >= v"0.4.0-dev+4319"
210+
simplevec = Base.svec(1, 2, Int64, "foo")
211+
iseq(x::SimpleVector, y::SimpleVector) = collect(x) == collect(y)
212+
end
213+
208214
iseq(x,y) = isequal(x,y)
209215
iseq(x::MyStruct, y::MyStruct) = (x.len == y.len && x.data == y.data)
210216
iseq(x::MyImmutable, y::MyImmutable) = (isequal(x.x, y.x) && isequal(x.y, y.y) && isequal(x.z, y.z))
211217
iseq(x::Union(EmptyTI, EmptyTT), y::Union(EmptyTI, EmptyTT)) = isequal(x.x, y.x)
212218
iseq(c1::Array{Base.Sys.CPUinfo}, c2::Array{Base.Sys.CPUinfo}) = length(c1) == length(c2) && all([iseq(c1[i], c2[i]) for i = 1:length(c1)])
213219
function iseq(c1::Base.Sys.CPUinfo, c2::Base.Sys.CPUinfo)
214-
for n in Base.Sys.CPUinfo.names
220+
for n in fieldnames(Base.Sys.CPUinfo)
215221
if getfield(c1, n) != getfield(c2, n)
216222
return false
217223
end
@@ -387,6 +393,7 @@ for compress in (true,false)
387393
@write fid bitsparamint
388394
@write fid bitsparamuint
389395
@write fid tuple_of_tuples
396+
VERSION >= v"0.4.0-dev+4319" && @write fid simplevec
390397

391398
# Make sure we can create groups (i.e., use HDF5 features)
392399
g = g_create(fid, "mygroup")
@@ -515,6 +522,7 @@ for compress in (true,false)
515522
@check fidr bitsparamint
516523
@check fidr bitsparamuint
517524
@check fidr tuple_of_tuples
525+
VERSION >= v"0.4.0-dev+4319" && @check fidr simplevec
518526

519527
x1 = read(fidr, "group1/x")
520528
@assert x1 == Any[1]
@@ -739,7 +747,7 @@ jldopen(fn, "r") do file
739747
@test reinterpret(UInt8, x.d) == 0x12
740748

741749
x = read(file, "x9")
742-
@test isa(x, (@compat Tuple))
750+
@test isa(x, Tuple)
743751
@test length(x) == 3
744752
@test x[1].x == 1
745753
@test isa(x[2], Tuple)

0 commit comments

Comments
 (0)