This repository has been archived by the owner on Sep 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathStats.lua
249 lines (217 loc) · 5.48 KB
/
Stats.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
local addonName, OQ = ...
local oq = OQ:mod() -- thank goodness i stumbled across this trick
local _ -- throw away (was getting taint warning; what happened blizz?)
local tbl = OQ.table
--------------------------------------------------------------------------
-- packet stats
--------------------------------------------------------------------------
PacketStatistics = {}
function PacketStatistics:new(max_cnt)
local o = tbl.new()
o._cnt = 0
o._max = max_cnt
o.array = tbl.new()
for i = 1, max_cnt do
o.array[i] = tbl.new()
o.array[i]._x = nil
o.array[i]._tm = nil
end
o._n = 0
o._aps = 0
o._dt = 0
o._mean = 0
setmetatable(o, {__index = PacketStatistics})
return o
end
--
-- used for averaging event times
--
function PacketStatistics:avg()
local t1 = nil
local t2 = nil
local n1 = 0
local n2 = 0
self._n = 0
self._aps = 0 -- avg per second
for i = 1, self._max do
if (self.array[i]._x ~= nil) then
self._n = self._n + 1
if (t2 == nil) then
t2 = self.array[i]._tm
n2 = self.array[i]._x
end
t1 = self.array[i]._tm
n1 = self.array[i]._x
end
end
if (self._n < 2) then
self._aps = 0
self._dt = 0
return 0
end
self._dt = t2 - t1
if (self._dt > 0) then
self._aps = (n2 - n1) / self._dt
end
return self._aps
end
function PacketStatistics:mean()
local n = 0
local sum = 0
for i = 1, self._max do
if (self.array[i]._x ~= nil) then
n = n + 1
sum = sum + self.array[i]._x
end
end
if (n == 0) then
self._mean = 0
else
self._mean = sum / n
end
end
function PacketStatistics:reset()
self._cnt = 0
for i = 1, self._max do
self.array[i]._x = nil
self.array[i]._tm = nil
end
self._n = 0
self._cnt = 0
self._aps = 0
self._dt = 0
self._mean = 0
end
function PacketStatistics:inc()
self:push(self._cnt)
self._cnt = self._cnt + 1
end
-- no-op recording nothing
--
function PacketStatistics:noop()
self:push(self._cnt)
end
function PacketStatistics:push(x, use_mean)
for i = self._max, 2, -1 do
self.array[i]._x = self.array[i - 1]._x
self.array[i]._tm = self.array[i - 1]._tm
end
self.array[1]._x = x
self.array[1]._tm = GetTime()
if (use_mean) then
self:mean()
else
self:avg()
end
end
function PacketStatistics:median()
local t = tbl.new()
for _, v in pairs(self.array) do
table.insert(t, v._x)
end
local median = oq.stats.median(t)
tbl.delete(t)
return median
end
oq.pkt_sent = PacketStatistics:new(50)
oq.pkt_recv = PacketStatistics:new(50)
oq.pkt_processed = PacketStatistics:new(50)
oq.pkt_drift = PacketStatistics:new(5)
oq.gmt_diff_track = PacketStatistics:new(100)
--------------------------------------------------------------------------
-- general stats
--------------------------------------------------------------------------
oq.stats = tbl.new()
-- Get the mean value of a table
function oq.stats.mean(t)
local sum = 0
local count = 0
for _, v in pairs(t) do
if type(v) == 'number' then
sum = sum + v
count = count + 1
end
end
return (sum / count)
end
-- Get the mode of a table. Returns a table of values.
-- Works on anything (not just numbers).
function oq.stats.mode(t)
local counts = tbl.new()
for _, v in pairs(t) do
if counts[v] == nil then
counts[v] = 1
else
counts[v] = counts[v] + 1
end
end
local biggestCount = 0
for _, v in pairs(counts) do
if (v > biggestCount) then
biggestCount = v
end
end
local temp = tbl.new()
for k, v in pairs(counts) do
if v == biggestCount then
table.insert(temp, k)
end
end
tbl.delete(counts)
return temp
end
-- Get the median of a table.
function oq.stats.median(t, skip_zero)
local temp = tbl.new()
-- deep copy table so that when we sort it, the original is unchanged
-- also weed out any non numbers
for _, v in pairs(t) do
if (type(v) == 'number') and ((skip_zero == nil) or (v > 0)) then
table.insert(temp, v)
end
end
table.sort(temp)
-- If we have an even number of table elements or odd.
local median = 0
local n = #temp
if (n > 0) then
if math.fmod(n, 2) == 0 then
-- return mean value of middle two elements
median = (temp[n / 2] + temp[(n / 2) + 1]) / 2
else
-- return middle element
median = temp[math.ceil(n / 2)]
end
end
tbl.delete(temp)
return median
end
-- Get the standard deviation of a table
function oq.stats.standardDeviation(t)
local m = oq.stats.mean(t)
local vm
local sum = 0
local count = 0
local result
for _, v in pairs(t) do
if type(v) == 'number' then
vm = v - m
sum = sum + (vm * vm)
count = count + 1
end
end
result = math.sqrt(sum / (count - 1))
return result
end
-- Get the max and min for a table
function oq.stats.maxmin(t)
local max = -math.huge
local min = math.huge
for _, v in pairs(t) do
if type(v) == 'number' then
max = math.max(max, v)
min = math.min(min, v)
end
end
return max, min
end