blob: f89908497efadc3bc189d75023ce3a8890376d1a [file] [log] [blame]
stgleb75c70412015-02-17 02:52:00 +02001import datetime
2import math
3
4from flask import json
5from sqlalchemy import sql
6from persistance.models import *
7
8
9#class displays measurement. Moved from storage_api_v_1 to avoid circular imports.
10class Measurement(object):
11 def __init__(self):
12 self.build = ""
13 self.build_type = 0 # GA/Master/Other
14 self.md5 = ""
15 self.name = ""
16 self.date = None
17 self.results = {
18 "": (float, float)
19 }
20
21 def __str__(self):
22 return self.build + " " + self.build_type + " " + \
23 self.md5 + " " + str(self.results)
24
25
26def mean(l):
27 n = len(l)
28
29 return sum(l) / n
30
31
32def stdev(l):
33 m = mean(l)
34 return math.sqrt(sum(map(lambda x: (x - m) ** 2, l)))
35
36
37def process_build_data(build):
38 for item in build.items():
39 if type(item[1]) is list:
40 m = mean(item[1])
41 s = stdev(item[1])
42 build[item[0]] = [m, s]
43
44
45#filling Param table with initial parameters.
46def add_io_params(session):
47 param1 = Param(name="operation", type='{"write", "randwrite", "read", "randread"}', descr="type of write operation")
48 param2 = Param(name="sync", type='{"a", "s"}', descr="Write mode synchronous/asynchronous")
49 param3 = Param(name="block size", type='{"1k", "2k", "4k", "8k", "16k", "32k", "64k", "128k", "256k"}')
50
51 session.add(param1)
52 session.add(param2)
53 session.add(param3)
54
55 session.commit()
56
57
58#function which adds particular build to database.
59def add_build(session, build_id, build_name, build_type, md5):
60 build = Build(type=build_type, build_id=build_id, name=build_name, md5=md5)
61 session.add(build)
62 session.commit()
63
64 return build.id
65
66
67#function insert particular result.
68def insert_results(session, build_id, lab_id, params_combination_id,
69 time=None, bandwith=0.0, meta=""):
70 result = Result(build_id=build_id, lab_id=lab_id, params_combination_id=params_combination_id, time=time,
71 bandwith=bandwith, meta=meta)
72 session.add(result)
73 session.commit()
74
75
76#function responsible for adding particular params combination to database
77def add_param_comb(session, *params):
78 params_names = sorted([s for s in dir(ParamCombination) if s.startswith('param_')])
79 d = zip(params_names, params)
80 where = ""
81
82 for item in d:
83 where = sql.and_(where, getattr(ParamCombination, item[0]) == item[1])
84
85 query = session.query(ParamCombination).filter(where)
86 rs = session.execute(query).fetchall()
87
88
89 if len(rs) == 0:
90 param_comb = ParamCombination()
91
92 for p in params_names:
93 i = int(p.split('_')[1])
94 param_comb.__setattr__('param_' + str(i), params[i - 1])
95
96 param = session.query(Param).filter(Param.id == i).one()
97 values = eval(param.type)
98
99 if params[i - 1] not in values:
100 values.add(params[i - 1])
101 param.type = str(values)
102
103 session.add(param_comb)
104 session.commit()
105 return param_comb.id
106 else:
107 return rs[0][0]
108
109
110def add_lab(lab_name):
111 pass
112
113
114#function store list of builds in database
115def add_data(data):
116 data = json.loads(data)
117 session = db.session()
118 add_io_params(session)
119
120 for build_data in data:
121 build_id = add_build(session,
122 build_data.pop("build_id"),
123 build_data.pop("name"),
124 build_data.pop("type"),
125 build_data.pop("iso_md5"),
126 )
127 date = build_data.pop("date")
128 date = datetime.datetime.strptime(date, "%a %b %d %H:%M:%S %Y")
129
130 for params, [bw, dev] in build_data.items():
131 param_comb_id = add_param_comb(session, *params.split(" "))
132 result = Result(param_combination_id=param_comb_id, build_id=build_id, bandwith=bw, date=date)
133 session.add(result)
134 session.commit()
135
136
137#function loads data by parametres described in *params tuple.
138def load_data(*params):
139 session = db.session()
140 params_names = sorted([s for s in dir(ParamCombination) if s.startswith('param_')])
141 d = zip(params_names, params)
142 where = ""
143
144 for item in d:
145 where = sql.and_(where, getattr(ParamCombination, item[0]) == item[1])
146
147 query = session.query(ParamCombination).filter(where)
148 rs = session.execute(query).fetchall()
149
150 ids = [r[0] for r in rs]
151
152 results = session.query(Result).filter(Result.param_combination_id.in_(ids))
153 rs = session.execute(results).fetchall()
154
155 return [r[5] for r in rs]
156
157
158#load all builds from database
159def load_all():
160 session = db.session()
161 r = session.query(Param).filter(Param.id == 1).all()
162 results = session.query(Result, Build, ParamCombination).join(Build).join(ParamCombination).all()
163
164 return results
165
166
167#function collecting all builds from database and filter it by names
168def collect_builds_from_db(*names):
169 results = load_all()
170 d = {}
171
172 for item in results:
173 result_data = item[0]
174 build_data = item[1]
175 param_combination_data = item[2]
176
177 if build_data.name not in d:
178 d[build_data.name] = [build_data, result_data, param_combination_data]
179 else:
180 d[build_data.name].append(result_data)
181 d[build_data.name].append(param_combination_data)
182
183 if len(names) == 0:
184 return {k: v for k, v in d.items()}
185
186 return {k: v for k, v in d.items() if k in names}
187
188
189#function creates measurement from data was extracted from database.
190def create_measurement(data):
191 build_data = data[0]
192
193 m = Measurement()
194 m.build = build_data.build_id
195 m.build_type = build_data.type
196 m.name = build_data.name
197 m.results = {}
198
199 for i in range(1, len(data), 2):
200 result = data[i]
201 param_combination = data[i + 1]
202
203 if not str(param_combination) in m.results:
204 m.results[str(param_combination)] = [result.bandwith]
205 else:
206 m.results[str(param_combination)] += [result.bandwith]
207
208 for k in m.results.keys():
209 m.results[k] = [mean(m.results[k]), stdev(m.results[k])]
210
211 return m
212
213
214#function preparing data for display plots.
215#Format {build_name : Measurement}
216def prepare_build_data(build_name):
217 session = db.session()
218 build = session.query(Build).filter(Build.name == build_name).first()
219 names = []
220
221 if build.type == 'GA':
222 names = [build_name]
223 else:
224 res = session.query(Build).filter(Build.type.in_(['GA', 'master', build.type])).all()
225 for r in res:
226 names.append(r.name)
227
228
229 d = collect_builds_from_db()
230 d = {k: v for k, v in d.items() if k in names}
231 results = {}
232
233 for data in d.keys():
234 m = create_measurement(d[data])
235 results[m.build_type] = m
236
237 return results
238
239
240#function getting list of all builds available to index page
241#returns list of dicts which contains data to display on index page.
242def builds_list():
243 res = []
244 builds = set()
245 data = load_all()
246
247 for item in data:
248 build = item[1]
249 result = item[0]
250
251 if not build.name in builds:
252 builds.add(build.name)
253 d = {}
254 d["type"] = build.type
255 d["url"] = build.name
256 d["date"] = result.date
257 d["name"] = build.name
258 res.append(d)
259
260 return res
261
262
263#Processing data from database.
264#List of dicts, where each dict contains build meta info and kev-value measurements.
265#key - param combination.
266#value - [mean, deviation]
267def get_builds_data(names=None):
268 d = collect_builds_from_db()
269
270 if not names is None:
271 d = {k: v for k, v in d.items() if k in names}
272 else:
273 d = {k: v for k, v in d.items()}
274 output = []
275
276 for key, value in d.items():
277 result = {}
278 build = value[0]
279 result["build_id"] = build.build_id
280 result["iso_md5"] = build.md5
281 result["type"] = build.type
282 result["date"] = "Date must be here"
283
284 for i in range(1, len(value), 2):
285 r = value[i]
286 param_combination = value[i + 1]
287
288 if not str(param_combination) in result:
289 result[str(param_combination)] = [r.bandwith]
290 else:
291 result[str(param_combination)].append(r.bandwith)
292
293 output.append(result)
294
295 for build in output:
296 process_build_data(build)
297
298 return output
299
300
301#Function for getting result to display table
302def get_data_for_table(build_name=""):
303 session = db.session()
304 build = session.query(Build).filter(Build.name == build_name).one()
305 names = []
306
307 #Get names of build that we need.
308 if build.type == 'GA':
309 names = [build_name]
310 else:
311 res = session.query(Build).filter(Build.type.in_(['GA', 'master', build.type])).all()
312 for r in res:
313 names.append(r.name)
314 #get data for particular builds.
315 return get_builds_data(names)
316
317
318if __name__ == '__main__':
319 # add_build("Some build", "GA", "bla bla")
320 json_data = '[{\
321 "randwrite a 256k": [16885, 1869],\
322 "randwrite s 4k": [79, 2],\
323 "read a 64k": [74398, 11618],\
324 "write s 1024k": [7490, 193],\
325 "randwrite a 64k": [14167, 4665],\
326 "build_id": "1",\
327 "randread a 1024k": [68683, 8604],\
328 "randwrite s 256k": [3277, 146],\
329 "write a 1024k": [24069, 660],\
330 "type": "GA",\
331 "write a 64k": [24555, 1006],\
332 "write s 64k": [1285, 57],\
333 "write a 256k": [24928, 503],\
334 "write s 256k": [4029, 192],\
335 "randwrite a 1024k": [23980, 1897],\
336 "randread a 64k": [27257, 17268],\
337 "randwrite s 1024k": [8504, 238],\
338 "randread a 256k": [60868, 2637],\
339 "randread a 4k": [3612, 1355],\
340 "read a 1024k": [71122, 9217],\
341 "date": "Thu Feb 12 19:11:56 2015",\
342 "write s 4k": [87, 3],\
343 "read a 4k": [88367, 6471],\
344 "read a 256k": [80904, 8930],\
345 "name": "GA - 6.0 GA",\
346 "randwrite s 1k": [20, 0],\
347 "randwrite s 64k": [1029, 34],\
348 "write s 1k": [21, 0],\
349 "iso_md5": "bla bla"\
350 },\
351 {\
352 "randwrite a 256k": [20212, 5690],\
353 "randwrite s 4k": [83, 6],\
354 "read a 64k": [89394, 3912],\
355 "write s 1024k": [8054, 280],\
356 "randwrite a 64k": [14595, 3245],\
357 "build_id": "2",\
358 "randread a 1024k": [83277, 9310],\
359 "randwrite s 256k": [3628, 433],\
360 "write a 1024k": [29226, 8624],\
361 "type": "master",\
362 "write a 64k": [25089, 790],\
363 "write s 64k": [1236, 30],\
364 "write a 256k": [30327, 9799],\
365 "write s 256k": [4049, 172],\
366 "randwrite a 1024k": [29000, 9302],\
367 "randread a 64k": [26775, 16319],\
368 "randwrite s 1024k": [8665, 1457],\
369 "randread a 256k": [63608, 16126],\
370 "randread a 4k": [3212, 1620],\
371 "read a 1024k": [89676, 4401],\
372 "date": "Thu Feb 12 19:11:56 2015",\
373 "write s 4k": [88, 3],\
374 "read a 4k": [92263, 5186],\
375 "read a 256k": [94505, 6868],\
376 "name": "6.1 Dev",\
377 "randwrite s 1k": [22, 3],\
378 "randwrite s 64k": [1105, 46],\
379 "write s 1k": [22, 0],\
380 "iso_md5": "bla bla"\
381 },\
382 {\
383 "randwrite a 256k": [16885, 1869],\
384 "randwrite s 4k": [79, 2],\
385 "read a 64k": [74398, 11618],\
386 "write s 1024k": [7490, 193],\
387 "randwrite a 64k": [14167, 4665],\
388 "build_id": "1",\
389 "randread a 1024k": [68683, 8604],\
390 "randwrite s 256k": [3277, 146],\
391 "write a 1024k": [24069, 660],\
392 "type": "sometype",\
393 "write a 64k": [24555, 1006],\
394 "write s 64k": [1285, 57],\
395 "write a 256k": [24928, 503],\
396 "write s 256k": [4029, 192],\
397 "randwrite a 1024k": [23980, 1897],\
398 "randread a 64k": [27257, 17268],\
399 "randwrite s 1024k": [8504, 238],\
400 "randread a 256k": [60868, 2637],\
401 "randread a 4k": [3612, 1355],\
402 "read a 1024k": [71122, 9217],\
403 "date": "Thu Feb 12 19:11:56 2015",\
404 "write s 4k": [87, 3],\
405 "read a 4k": [88367, 6471],\
406 "read a 256k": [80904, 8930],\
407 "name": "somedev",\
408 "randwrite s 1k": [20, 0],\
409 "randwrite s 64k": [1029, 34],\
410 "write s 1k": [21, 0],\
411 "iso_md5": "bla bla"\
412 }]'
413
414 # json_to_db(json_data)
415 # print load_data()
416 add_data(json_data)
417
418 print collect_builds_from_db()
419 print prepare_build_data('6.1 Dev')
420 print builds_list()
421 print get_data_for_table('somedev')