23 import matplotlib.pyplot 
as plt
    25 from playhouse.shortcuts 
import model_to_dict
    26 from typing 
import List, Dict
    27 from graphviz 
import Digraph
    30 CONV={
"us": 1000, 
"ms": 1000*1000}
    33     for i 
in range(len(timeline)-1):
    34         color = [
'red', 
'green', 
'blue', 
'yellow', 
'cyan'][i%5]
    35         start  = timeline[i][
'time']
    36         end    = timeline[i+1][
'time']
    37         label  = timeline[i][
'state']
    39         plt.hlines(offset, start, end, colors=color, lw=5)
    40         plt.text(start, offset, label, rotation=90)
    42     start  = timeline[0][
'time']
    43     end    = timeline[-1][
'time']
    44     label  = timeline[-1][
'state']
    45     plt.text(end, offset, label, rotation=90)
    47     center = (end-start)/2
    48     label  = timeline[0][
'op'] + 
": " + str(round((end-start)/1000000,3)) + 
"ms"    49     plt.text(start+center, offset+0.01, label)
    54     for times 
in time_table:
    55         times.sort(key=
lambda time: time[
'time'])
    58             ref_time = times[0][
'time']
    60             ref_time = 
min(times[0][
'time'], ref_time)
    62     for times 
in time_table:
    64             time[
'time']=time[
'time']-ref_time
    71         out.append(model_to_dict(m))
    76         t[tag_name] = tag_value
    77 queues_tag_append=times_tag_append
    80     mx=
max([q[
'max'] 
for q 
in queue])
    81     mx=0.0000001 
if mx == 0 
else mx 
    83     qnr  =[q[
'nr']           
for q 
in queue]
    84     xdata=[q[
'time']         
for q 
in queue]
    85     ydata=[q[
'avg']          
for q 
in queue]
    86     _min =[q[
'min']          
for q 
in queue]
    87     _max =[q[
'max']          
for q 
in queue]
    88     dev  =[math.sqrt(q[
'dev']) 
for q 
in queue]
    89     avi  =[q[
'avg']-math.sqrt(q[
'dev']) 
for q 
in queue]
    90     ava  =[q[
'avg']+math.sqrt(q[
'dev']) 
for q 
in queue]
    92     plt.plot(xdata, [offset+y/mx 
for y 
in ydata], 
'or')
    93     plt.plot(xdata, [offset+y/mx 
for y 
in ydata], 
'-', color=
'gray')
    94     plt.fill_between(xdata,
    95                      [offset+y/mx 
for y 
in avi],
    96                      [offset+y/mx 
for y 
in ava], color=
'gray', alpha=0.2)
    97     plt.fill_between(xdata,
    98                      [offset+y/mx 
for y 
in _min],
    99                      [offset+y/mx 
for y 
in _max], color=
'green', alpha=0.2)
   101     for x,y,nr,i,a,d 
in zip(xdata, ydata, qnr, _min, _max, dev ):
   102         plt.text(x,offset+y/mx, f
"{round(y,2)} |{round(a,2)}|")
   104 def draw_timelines(time_table, queue_table, client_start_time, queue_start_time,
   105                    time_unit: str, show_queues: bool, maximize: bool):
   106     cursor={
"x0":0, 
"y0":0, 
"x1": 0, 
"y1": 0, 
"on": 
False}
   110             cursor.update({ 
"on": 
True })
   111         elif event.key == 
'd':
   113                 for an 
in undo.pop():
   117     def onrelease(event):
   120         cursor.update({ 
"x1": event.xdata, 
"y1": event.ydata })
   121         cursor.update({ 
"on": 
False })
   123         an1=event.inaxes.axvspan(cursor[
"x0"], cursor[
"x1"], facecolor=
'0.9', alpha=.5)
   124         an2=event.inaxes.annotate(
'', xy=(cursor[
"x0"], cursor[
"y0"]),
   125                                   xytext=(cursor[
"x1"], cursor[
"y0"]),
   126                                   xycoords=
'data', textcoords=
'data',
   127                                   arrowprops={
'arrowstyle': 
'|-|'})
   128         an3=event.inaxes.annotate(str(round((cursor[
"x1"]-cursor[
"x0"])/CONV[time_unit],2))+f
" {time_unit}",
   129                                   xy=(
min(cursor[
"x1"], cursor[
"x0"])+
   130                                       abs(cursor[
"x1"]-cursor[
"x0"])/2, 0.5+cursor[
"y0"]),
   131                                   ha=
'center', va=
'center')
   132         undo.append([an1, an2, an3])
   138         cursor.update({ 
"x0": event.xdata, 
"y0": event.ydata })
   141     fig.canvas.mpl_connect(
'key_press_event', onpress)
   142     fig.canvas.mpl_connect(
'button_press_event', onclick)
   143     fig.canvas.mpl_connect(
'button_release_event', onrelease)
   146     plt.subplot({
True:211, 
False:111}[show_queues])
   148     for times 
in time_table:
   152     plt.yticks(np.arange(0.0, offset, -2), [t[0][
'op'] 
for t 
in time_table])
   157         for qt,subp,qstt 
in zip(queue_table, [223,224], queue_start_time):
   164             plt.axvline(x=(client_start_time-qstt))
   165             plt.yticks(np.arange(0.0, offset, -2), [t[0][
'op'] 
for t 
in qt])
   170         mng = plt.get_current_fig_manager()
   171         mng.window.maximize()
   175     for q_conf 
in [[
"runq", 
"wail", 
"fom-active"],
   176                    [
"stob-ioq-inflight", 
"stob-ioq-queued"]]:
   177         queue_table.append([])
   178         loc_nr = queues.select(fn.MAX(queues.locality)).where(queues.type==q_conf[0]).scalar()
   179         for nr 
in range(loc_nr+1):
   180             for queuei 
in q_conf:
   181                 left  = queues.select().where((queues.min>-1)
   182                                               &(queues.locality==nr)
   183                                               &(queues.type==queuei)
   184                                               &(queues.time<client_start_time)).limit(qrange)
   185                 right = queues.select().where((queues.min>-1)
   186                                               &(queues.locality==nr)
   187                                               &(queues.type==queuei)
   188                                               &(queues.time>=client_start_time)).limit(qrange)
   189                 stmt = [*left, *right]
   192                 _min = queues.select(fn.MIN(queues.min)).where((queues.min>-1)
   193                                                                &(queues.locality==nr)
   194                                                                &(queues.type==queuei)).scalar()
   195                 _max = queues.select(fn.MAX(queues.max)).where((queues.min>-1)
   196                                                                &(queues.locality==nr)
   197                                                                &(queues.type==queuei)).scalar()
   198                 queues_tag_append(q_d, 
'op', f
"{queuei}#{nr}[{_min}..{_max}]")
   199                 queue_table[-1].append(q_d)
   208 <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">   217     label = 
"<BR/>".join([f
"{k}={v}" for (k,v) 
in attrs.items()])
   218     g.node(name, node_template.format(header, label))
   221     c = 
lambda attr: re.sub(
"M0_AVI_.*_ATTR_", 
"", attr)
   222     attrd = 
query2dlist(attr.select().where( (attr.entity_id==lid)
   224     attrs = dict([(
c(a[
'name']), a[
'val']) 
for a 
in attrd])
   228     def pid_get(lid_rec, flags: str):
   230         return { 
'C' : lid_rec[1],
   231                  'S' : lid_rec[2] }[pidt]
   234     #           relation    |      from     |     to        | table or direct| flags   235     #                       | table/mapping | table/mapping |     mapping    |   236     schema = [("client_id"  ,  "client_id"  , "dix_id"      , ""             , "C1"),   237               ("cas_id"     ,  "cas_id"     , "rpc_id"      , "cas_to_rpc"   , "C" ),   238               ("crpc_id"    ,  "crpc_id"    , "srpc_id"     , ""             , "C1"),   239               ("crpc_id"    ,  "rpc_id"     , "bulk_id"     , "bulk_to_rpc"  , "Cs"),   240               ("srpc_id"    ,  "srpc_id"    , "fom_id"      , ""             , "S1"),   241               ("fom_id"     ,  "fom_id"     , "tx_id"       , ""             , "S1"),   242               ("tx_id"      ,  ""           , ""            , ""             , "Sl"),   243               ("fom_id"     ,  "fom_id"     , "crow_fom_id" , ""             , "S1"),   244               ("crow_fom_id",  "crow_fom_id", "crow_tx_id"  , ""             , "S1"),   245               ("crow_tx_id" ,  ""           , ""            , ""             , "Sl")]   246     # flags: '1' - one to one mapping, 's' - stash samples, 'l' - leaf element   250     for rel,fr,to,map,flags 
in schema:
   251         layer_ids=set([(r[rel], r[
'cli_pid'], r[
'srv_pid']) 
for r 
in relations 
if r[rel] 
is not None])
   252         for lid_rec 
in layer_ids:
   254             pid = pid_get(lid_rec, flags)
   260                 tid = 
next(r[to] 
for r 
in relations 
if r[fr]==lid)
   262                     graph.edge(f
"{lid}", f
"{tid}")
   265             cursor = DB.execute_sql(f
"SELECT {to} FROM {map} WHERE {fr}={lid} and pid={pid}")
   266             for (tid,) 
in cursor:
   267                 graph.edge(f
"{lid}", f
"{tid}")
   269                     stash.append((tid,to,pid))
   271     for lid,rel,pid 
in stash:
 
def draw_queue_line(queue, offset)
 
def prepare_time_table(time_table)
 
static struct m0_addb2_callback c
 
static long long max(long long a, long long b)
 
static long long min(long long a, long long b)
 
def draw_timeline(timeline, offset)