trac-tim.lmt /size: 5468 b    last modification: 2021-10-28 13:51
1if not modules then modules = { } end modules ['trac-tim'] = {
2    version   = 1.001,
3    comment   = "companion to m-timing.tex",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local format, gsub = string.format, string.gsub
10local concat, sort = table.concat, table.sort
11local next, tonumber = next, tonumber
12
13moduledata          = moduledata or { }
14local progress      = moduledata.progress or { }
15moduledata.progress = progress
16
17local report_timing = logs.reporter("timing")
18
19if not nodes then nodes = { } end -- when loaded in mtxrun
20
21progress.defaultfilename = ((tex and tex.jobname) or "whatever") .. "-luatex-progress"
22
23-- storage
24
25function progress.store()
26    nodes.snapshots.takesample()
27end
28
29function progress.save(name)
30    local filename = (name or progress.defaultfilename) .. ".lut"
31    report_timing("saving data in %a",filename)
32    table.save(filename,nodes.snapshots.getsamples())
33    nodes.snapshots.resetsamples()
34end
35
36-- conversion
37
38local processed = { }
39
40local function convert(name)
41    name = name ~= "" and name or progress.defaultfilename
42    if not processed[name] then
43        local pages = 0
44        local names = { }
45        local top   = { }
46        local bot   = { }
47        local siz   = { }
48        local paths = { }
49        local data  = table.load(name .. ".lut")
50        if data then
51            pages = #data
52            if pages > 1 then
53
54                local factor = 100
55
56                local function path(tag,subtag,tagname)
57                    local tagname = tag .. ": " .. subtag
58                    local b, t, s = nil, nil, { }
59                    for k=1,#data do
60                        local v = data[k][tag]
61                        v = v and v[subtag]
62                        if v then
63                            if type(v) == "table" then
64                                set[tagname] = tonumber(v.set)
65                                v = tonumber(v.top)
66                            else
67                                v = tonumber(v)
68                            end
69                            if v then
70                                if b then
71                                    if v > t then t = v end
72                                    if v < b then b = v end
73                                else
74                                    t = v
75                                    b = v
76                                end
77                            else
78                                v = 0
79                            end
80                        else
81                            v = 0
82                        end
83                        s[k] = v
84                    end
85                    if not b then
86                        -- safeguard against updates
87                        b = 0
88                        t = 0
89                    end
90                    top[tagname] = gsub(format("%.3f",t),"%.000$","")
91                    bot[tagname] = gsub(format("%.3f",b),"%.000$","")
92                    local delta = t - b
93                    if delta == 0 then
94                        delta = 1
95                    else
96                        delta = factor/delta
97                    end
98                    for k=1,#s do
99                        s[k] = format("(%.3f,%.3f)",k,(s[k]-b)*delta)
100                    end
101                    paths[tagname] = concat(s,"--")
102                    return tagname
103                end
104
105                local function collect(category)
106                    if data[1][category] then
107                        local keys = { }
108                        for k=1,#data do
109                            for k, v in next, data[k][category] do
110                                keys[k] = true
111                            end
112                        end
113                        for k=1,#data do
114                            local m = data[k][category]
115                            for k, v in next, keys do
116                                if not m[k] then m[k] = 0 end
117                            end
118                        end
119                        for k in next, keys do
120                            names[#names+1] = path(category,k)
121                        end
122                    end
123                end
124
125                collect("nodes")
126                collect("stock")
127                collect("memories")
128                collect("variables")
129                collect("texvariables")
130                collect("luavariables")
131                collect("texcallbacks")
132                collect("mpcallbacks")
133                collect("backendcallbacks")
134
135                pages = pages - 1 -- hm
136            end
137        end
138
139        sort(names)
140
141        processed[name] = {
142            names = names,
143            top   = top,
144            bot   = bot,
145            set   = set,
146            pages = pages,
147            paths = paths,
148        }
149    end
150    return processed[name]
151end
152
153progress.convert = convert
154
155function progress.set(name,tag)
156    return convert(name).set[tag] or 0
157end
158
159function progress.bot(name,tag)
160    return convert(name).bot[tag] or 0
161end
162
163function progress.top(name,tag)
164    return convert(name).top[tag] or 0
165end
166
167function progress.pages(name,tag)
168    return convert(name).pages or 0
169end
170
171function progress.path(name,tag)
172    return convert(name).paths[tag] or "origin"
173end
174
175function progress.names(name)
176    return convert(name).names or { }
177end
178
179