trac-tim.lua /size: 4285 b    last modification: 2020-07-01 14:35
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.parameters      = nodes and nodes.snapshots.getparameters
22progress.defaultfilename = ((tex and tex.jobname) or "whatever") .. "-luatex-progress"
23
24-- storage
25
26function progress.store()
27    nodes.snapshots.takesample()
28end
29
30function progress.save(name)
31    local filename = (name or progress.defaultfilename) .. ".lut"
32    report_timing("saving data in %a",filename)
33    table.save(filename,nodes.snapshots.getsamples())
34    nodes.snapshots.resetsamples()
35end
36
37-- conversion
38
39local processed  = { }
40local parameters = progress.parameters()
41
42local function convert(name)
43    name = name ~= "" and name or progress.defaultfilename
44    if not processed[name] then
45        local names, top, bot, pages, paths, keys = { }, { }, { }, 0, { }, { }
46        local data = table.load(name .. ".lut")
47        if data then
48            pages = #data
49            if pages > 1 then
50                local factor = 100
51                for k=1,#data do
52                    for k, v in next, data[k].node_memory do
53                        keys[k] = true
54                    end
55                end
56                for k=1,#data do
57                    local m = data[k].node_memory
58                    for k, v in next, keys do
59                        if not m[k] then m[k] = 0 end
60                    end
61                end
62                local function path(tag,subtag)
63                    local b, t, s = nil, nil, { }
64                    for k=1,#data do
65                        local v = data[k][tag]
66                        v = v and (subtag and v[subtag]) or v
67                        if v then
68                            v = tonumber(v)
69                            if b then
70                                if v > t then t = v end
71                                if v < b then b = v end
72                            else
73                                t = v
74                                b = v
75                            end
76                            s[k] = v
77                        else
78                            s[k] = 0
79                        end
80                    end
81                    local tagname = subtag or tag
82                    top[tagname] = gsub(format("%.3f",t),"%.000$","")
83                    bot[tagname] = gsub(format("%.3f",b),"%.000$","")
84                    local delta = t-b
85                    if delta == 0 then
86                        delta = 1
87                    else
88                        delta = factor/delta
89                    end
90                    for k=1,#s do
91                        s[k] = format("(%.3f,%.3f)",k,(s[k]-b)*delta)
92                    end
93                    paths[tagname] = concat(s,"--")
94                end
95                for i=1,#parameters do
96                    path(parameters[i])
97                end
98                for tag, _ in next, keys do
99                    path("node_memory",tag)
100                    names[#names+1] = tag
101                end
102                pages = pages - 1
103            end
104        end
105        sort(names)
106        processed[name] = {
107            names = names,
108            top   = top,
109            bot   = bot,
110            pages = pages,
111            paths = paths,
112        }
113    end
114    return processed[name]
115end
116
117progress.convert = convert
118
119function progress.bot(name,tag)
120    return convert(name).bot[tag] or 0
121end
122
123function progress.top(name,tag)
124    return convert(name).top[tag] or 0
125end
126
127function progress.pages(name,tag)
128    return convert(name).pages or 0
129end
130
131function progress.path(name,tag)
132    return convert(name).paths[tag] or "origin"
133end
134
135function progress.nodes(name)
136    return convert(name).names or { }
137end
138
139