@@ -5,37 +5,57 @@ const VERSIONS = Dict(
55)
66
77# TODO : Add any new types as they're added
8- const SUPPORTED_TYPES = Set{Type}((
9- BenchmarkGroup,
10- Parameters,
11- TagFilter,
12- Trial,
13- TrialEstimate,
14- TrialJudgement,
15- TrialRatio,
16- LinuxPerf. Stats,
17- LinuxPerf. ThreadStats,
18- LinuxPerf. Counter,
19- LinuxPerf. EventType
20- ))
21- const LOWERED_TO_SUPPORTED_TYPES = Dict{Symbol,Type}(
22- Base. typename(x). name => x for x in SUPPORTED_TYPES
8+ const SUPPORTED_TYPES = Dict{Symbol,Type}(
9+ Base. typename(x). name => x for x in [
10+ BenchmarkGroup,
11+ Parameters,
12+ TagFilter,
13+ Trial,
14+ TrialEstimate,
15+ TrialJudgement,
16+ TrialRatio,
17+ ]
2318)
2419# n.b. Benchmark type not included here, since it is gensym'd
2520
26- function JSON. lower(x:: Union{SUPPORTED_TYPES...} )
21+ function JSON. lower(x:: Union{values( SUPPORTED_TYPES) ...} )
2722 d = Dict{String,Any}()
2823 T = typeof(x)
2924 for i in 1 : nfields(x)
3025 name = String(fieldname(T, i))
3126 field = getfield(x, i)
3227 ft = typeof(field)
33- value = ( ft in SUPPORTED_TYPES) ? JSON. lower(field) : field
28+ value = ft <: get ( SUPPORTED_TYPES, nameof(ft), Union{} ) ? JSON. lower(field) : field
3429 d[name] = value
3530 end
3631 return [string(nameof(typeof(x))), d]
3732end
3833
34+ # Recovers LinuxPerf.Stats from serialized form
35+ function _convert(:: Type{Union{Nothing,LinuxPerf.Stats}} , d)
36+ if isnothing(d)
37+ return nothing
38+ end
39+ return LinuxPerf. Stats(_convert.(LinuxPerf. ThreadStats, d[" threads" ]))
40+ end
41+ function _convert(:: Type{LinuxPerf.ThreadStats} , d:: Dict{String} )
42+ return LinuxPerf. ThreadStats(
43+ d[" pid" ],
44+ [
45+ [_convert(LinuxPerf. Counter, counter) for counter in group] for
46+ group in d[" groups" ]
47+ ],
48+ )
49+ end
50+ function _convert(:: Type{LinuxPerf.Counter} , d:: Dict{String} )
51+ return LinuxPerf. Counter(
52+ _convert(LinuxPerf. EventType, d[" event" ]), d[" value" ], d[" enabled" ], d[" running" ]
53+ )
54+ end
55+ function _convert(:: Type{LinuxPerf.EventType} , d:: Dict{String} )
56+ return LinuxPerf. EventType(d[" category" ], d[" event" ])
57+ end
58+
3959# a minimal 'eval' function, mirroring KeyTypes, but being slightly more lenient
4060safeeval(@nospecialize x) = x
4161safeeval(x:: QuoteNode ) = x. value
@@ -45,25 +65,22 @@ function safeeval(x::Expr)
4565 x. head === :tuple && return ((safeeval(a) for a in x. args). .. ,)
4666 return x
4767end
48- recover(:: Nothing ) = nothing
4968function recover(x:: Vector )
5069 length(x) == 2 || throw(ArgumentError(" Expecting a vector of length 2" ))
5170 typename = x[1 ]:: String
5271 fields = x[2 ]:: Dict
5372 startswith(typename, " BenchmarkTools." ) &&
5473 (typename = typename[(sizeof(" BenchmarkTools." ) + 1 ): end ])
55- T = LOWERED_TO_SUPPORTED_TYPES [Symbol(typename)]
74+ T = SUPPORTED_TYPES [Symbol(typename)]
5675 fc = fieldcount(T)
5776 xs = Vector{Any}(undef, fc)
5877 for i in 1 : fc
5978 ft = fieldtype(T, i)
6079 fn = String(fieldname(T, i))
61- if ft == Union{Nothing, LinuxPerf. Stats} || ft in SUPPORTED_TYPES
80+ if ft == Union{Nothing,LinuxPerf. Stats}
81+ xsi = _convert(ft, fields[fn])
82+ elseif ft <: get (SUPPORTED_TYPES, nameof(ft), Union{})
6283 xsi = recover(fields[fn])
63- elseif ft == Vector{LinuxPerf. ThreadStats}
64- xsi = recover.(fields[fn])
65- elseif ft == Vector{Vector{LinuxPerf. Counter}}
66- xsi = [[recover(c) for c in t] for t in fields[fn]]
6784 else
6885 xsi = convert(ft, fields[fn])
6986 end
@@ -124,7 +141,7 @@ function save(io::IO, args...)
124141 " in the order it appears in the input."
125142 )
126143 continue
127- elseif typeof (arg) ∉ SUPPORTED_TYPES
144+ elseif ! (arg isa get( SUPPORTED_TYPES, nameof(typeof(arg)), Union{}))
128145 throw(ArgumentError(" Only BenchmarkTools types can be serialized." ))
129146 end
130147 push!(goodargs, arg)
0 commit comments