Lines Matching refs:self

194 	def __init__(self, task, param=None, parent=None):
195 super(Thread, self).__init__(parent)
196 self.task = task
197 self.param = param
199 def run(self):
201 if self.param is None:
202 done, result = self.task()
204 done, result = self.task(self.param)
205 self.done.emit(result)
213 def __init__(self, glb, params, parent=None):
214 super(TreeModel, self).__init__(parent)
215 self.glb = glb
216 self.params = params
217 self.root = self.GetRoot()
218 self.last_row_read = 0
220 def Item(self, parent):
224 return self.root
226 def rowCount(self, parent):
227 result = self.Item(parent).childCount()
230 self.dataChanged.emit(parent, parent)
233 def hasChildren(self, parent):
234 return self.Item(parent).hasChildren()
236 def headerData(self, section, orientation, role):
238 return self.columnAlignment(section)
243 return self.columnHeader(section)
245 def parent(self, child):
247 if child_item is self.root:
250 return self.createIndex(parent_item.getRow(), 0, parent_item)
252 def index(self, row, column, parent):
253 child_item = self.Item(parent).getChildItem(row)
254 return self.createIndex(row, column, child_item)
256 def DisplayData(self, item, index):
259 def FetchIfNeeded(self, row):
260 if row > self.last_row_read:
261 self.last_row_read = row
262 if row + 10 >= self.root.child_count:
263 self.fetcher.Fetch(glb_chunk_sz)
265 def columnAlignment(self, column):
268 def columnFont(self, column):
271 def data(self, index, role):
273 return self.columnAlignment(index.column())
275 return self.columnFont(index.column())
279 return self.DisplayData(item, index)
285 def __init__(self, parent=None):
286 super(TableModel, self).__init__(parent)
287 self.child_count = 0
288 self.child_items = []
289 self.last_row_read = 0
291 def Item(self, parent):
295 return self
297 def rowCount(self, parent):
298 return self.child_count
300 def headerData(self, section, orientation, role):
302 return self.columnAlignment(section)
307 return self.columnHeader(section)
309 def index(self, row, column, parent):
310 return self.createIndex(row, column, self.child_items[row])
312 def DisplayData(self, item, index):
315 def FetchIfNeeded(self, row):
316 if row > self.last_row_read:
317 self.last_row_read = row
318 if row + 10 >= self.child_count:
319 self.fetcher.Fetch(glb_chunk_sz)
321 def columnAlignment(self, column):
324 def columnFont(self, column):
327 def data(self, index, role):
329 return self.columnAlignment(index.column())
331 return self.columnFont(index.column())
335 return self.DisplayData(item, index)
367 def __init__(self, parent, finder, is_reg_expr=False):
368 self.finder = finder
369 self.context = []
370 self.last_value = None
371 self.last_pattern = None
376 self.textbox = QComboBox()
377 self.textbox.setEditable(True)
378 self.textbox.currentIndexChanged.connect(self.ValueChanged)
380 self.progress = QProgressBar()
381 self.progress.setRange(0, 0)
382 self.progress.hide()
385 self.pattern = QCheckBox("Regular Expression")
387 self.pattern = QCheckBox("Pattern")
388 self.pattern.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
390 self.next_button = QToolButton()
391 self.next_button.setIcon(parent.style().standardIcon(QStyle.SP_ArrowDown))
392 self.next_button.released.connect(lambda: self.NextPrev(1))
394 self.prev_button = QToolButton()
395 self.prev_button.setIcon(parent.style().standardIcon(QStyle.SP_ArrowUp))
396 self.prev_button.released.connect(lambda: self.NextPrev(-1))
398 self.close_button = QToolButton()
399 self.close_button.setIcon(parent.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
400 self.close_button.released.connect(self.Deactivate)
402 self.hbox = QHBoxLayout()
403 self.hbox.setContentsMargins(0, 0, 0, 0)
405 self.hbox.addWidget(label)
406 self.hbox.addWidget(self.textbox)
407 self.hbox.addWidget(self.progress)
408 self.hbox.addWidget(self.pattern)
409 self.hbox.addWidget(self.next_button)
410 self.hbox.addWidget(self.prev_button)
411 self.hbox.addWidget(self.close_button)
413 self.bar = QWidget()
414 self.bar.setLayout(self.hbox)
415 self.bar.hide()
417 def Widget(self):
418 return self.bar
420 def Activate(self):
421 self.bar.show()
422 self.textbox.lineEdit().selectAll()
423 self.textbox.setFocus()
425 def Deactivate(self):
426 self.bar.hide()
428 def Busy(self):
429 self.textbox.setEnabled(False)
430 self.pattern.hide()
431 self.next_button.hide()
432 self.prev_button.hide()
433 self.progress.show()
435 def Idle(self):
436 self.textbox.setEnabled(True)
437 self.progress.hide()
438 self.pattern.show()
439 self.next_button.show()
440 self.prev_button.show()
442 def Find(self, direction):
443 value = self.textbox.currentText()
444 pattern = self.pattern.isChecked()
445 self.last_value = value
446 self.last_pattern = pattern
447 self.finder.Find(value, direction, pattern, self.context)
449 def ValueChanged(self):
450 value = self.textbox.currentText()
451 pattern = self.pattern.isChecked()
452 index = self.textbox.currentIndex()
453 data = self.textbox.itemData(index)
456 self.textbox.setItemData(index, pattern)
458 self.pattern.setChecked(data)
459 self.Find(0)
461 def NextPrev(self, direction):
462 value = self.textbox.currentText()
463 pattern = self.pattern.isChecked()
464 if value != self.last_value:
465 index = self.textbox.findText(value)
468 index = self.textbox.count()
469 self.textbox.addItem(value, pattern)
470 self.textbox.setCurrentIndex(index)
473 self.textbox.setItemData(index, pattern)
474 elif pattern != self.last_pattern:
476 index = self.textbox.currentIndex()
477 self.textbox.setItemData(index, pattern)
478 self.Find(direction)
480 def NotFound(self):
481 QMessageBox.information(self.bar, "Find", "'" + self.textbox.currentText() + "' not found")
487 def __init__(self, glb, params, row, parent_item):
488 self.glb = glb
489 self.params = params
490 self.row = row
491 self.parent_item = parent_item
492 self.query_done = False
493 self.child_count = 0
494 self.child_items = []
496 self.level = parent_item.level + 1
498 self.level = 0
500 def getChildItem(self, row):
501 return self.child_items[row]
503 def getParentItem(self):
504 return self.parent_item
506 def getRow(self):
507 return self.row
509 def childCount(self):
510 if not self.query_done:
511 self.Select()
512 if not self.child_count:
514 return self.child_count
516 def hasChildren(self):
517 if not self.query_done:
519 return self.child_count > 0
521 def getData(self, column):
522 return self.data[column]
528 def __init__(self, glb, params, row, comm_id, thread_id, call_path_id, time, insn_cnt, cyc_cnt, branch_count, parent_item):
529 super(CallGraphLevelTwoPlusItemBase, self).__init__(glb, params, row, parent_item)
530 self.comm_id = comm_id
531 self.thread_id = thread_id
532 self.call_path_id = call_path_id
533 self.insn_cnt = insn_cnt
534 self.cyc_cnt = cyc_cnt
535 self.branch_count = branch_count
536 self.time = time
538 def Select(self):
539 self.query_done = True
540 query = QSqlQuery(self.glb.db)
541 if self.params.have_ipc:
550 " WHERE parent_call_path_id = " + str(self.call_path_id) +
551 " AND comm_id = " + str(self.comm_id) +
552 " AND thread_id = " + str(self.thread_id) +
556 if self.params.have_ipc:
564 child_item = CallGraphLevelThreeItem(self.glb, self.params, self.child_count, self.comm_id, self.thread_id, query.value(0), query.value(1), query.value(2), query.value(3), int(query.value(4)), insn_cnt, cyc_cnt, branch_count, self)
565 self.child_items.append(child_item)
566 self.child_count += 1
572 def __init__(self, glb, params, row, comm_id, thread_id, call_path_id, name, dso, count, time, insn_cnt, cyc_cnt, branch_count, parent_item):
573 super(CallGraphLevelThreeItem, self).__init__(glb, params, row, comm_id, thread_id, call_path_id, time, insn_cnt, cyc_cnt, branch_count, parent_item)
575 if self.params.have_ipc:
580 self.data = [ name, dso, str(count), str(time), PercentToOneDP(time, parent_item.time), str(insn_cnt), insn_pcnt, str(cyc_cnt), cyc_pcnt, ipc, str(branch_count), br_pcnt ]
582 self.data = [ name, dso, str(count), str(time), PercentToOneDP(time, parent_item.time), str(branch_count), PercentToOneDP(branch_count, parent_item.branch_count) ]
583 self.dbid = call_path_id
589 def __init__(self, glb, params, row, comm_id, thread_id, pid, tid, parent_item):
590 super(CallGraphLevelTwoItem, self).__init__(glb, params, row, comm_id, thread_id, 1, 0, 0, 0, 0, parent_item)
591 if self.params.have_ipc:
592 self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", "", "", "", "", "", ""]
594 self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", ""]
595 self.dbid = thread_id
597 def Select(self):
598 super(CallGraphLevelTwoItem, self).Select()
599 for child_item in self.child_items:
600 self.time += child_item.time
601 self.insn_cnt += child_item.insn_cnt
602 self.cyc_cnt += child_item.cyc_cnt
603 self.branch_count += child_item.branch_count
604 for child_item in self.child_items:
605 child_item.data[4] = PercentToOneDP(child_item.time, self.time)
606 if self.params.have_ipc:
607 child_item.data[6] = PercentToOneDP(child_item.insn_cnt, self.insn_cnt)
608 child_item.data[8] = PercentToOneDP(child_item.cyc_cnt, self.cyc_cnt)
609 child_item.data[11] = PercentToOneDP(child_item.branch_count, self.branch_count)
611 child_item.data[6] = PercentToOneDP(child_item.branch_count, self.branch_count)
617 def __init__(self, glb, params, row, comm_id, comm, parent_item):
618 super(CallGraphLevelOneItem, self).__init__(glb, params, row, parent_item)
619 if self.params.have_ipc:
620 self.data = [comm, "", "", "", "", "", "", "", "", "", "", ""]
622 self.data = [comm, "", "", "", "", "", ""]
623 self.dbid = comm_id
625 def Select(self):
626 self.query_done = True
627 query = QSqlQuery(self.glb.db)
631 " WHERE comm_id = " + str(self.dbid))
633 child_item = CallGraphLevelTwoItem(self.glb, self.params, self.child_count, self.dbid, query.value(0), query.value(1), query.value(2), self)
634 self.child_items.append(child_item)
635 self.child_count += 1
641 def __init__(self, glb, params):
642 super(CallGraphRootItem, self).__init__(glb, params, 0, None)
643 self.dbid = 0
644 self.query_done = True
653 child_item = CallGraphLevelOneItem(glb, params, self.child_count, query.value(0), query.value(1), self)
654 self.child_items.append(child_item)
655 self.child_count += 1
661 def __init__(self, glb, parent=None):
662 self.have_ipc = IsSelectable(glb.db, "calls", columns = "insn_count, cyc_count")
668 def __init__(self, glb, parent=None):
669 super(CallGraphModelBase, self).__init__(glb, CallGraphModelParams(glb), parent)
671 def FindSelect(self, value, pattern, query):
678 if not self.glb.dbref.is_sqlite3:
689 self.DoFindSelect(query, match)
691 def Found(self, query, found):
693 return self.FindPath(query)
696 def FindValue(self, value, pattern, query, last_value, last_pattern):
700 self.FindSelect(value, pattern, query)
702 return self.Found(query, found)
704 def FindNext(self, query):
708 return self.Found(query, found)
710 def FindPrev(self, query):
714 return self.Found(query, found)
716 def FindThread(self, c):
718 ids = self.FindValue(c.value, c.pattern, c.query, c.last_value, c.last_pattern)
720 ids = self.FindNext(c.query)
722 ids = self.FindPrev(c.query)
725 def Find(self, value, direction, pattern, context, callback):
727 def __init__(self, *x):
728 self.value, self.direction, self.pattern, self.query, self.last_value, self.last_pattern = x
729 def Update(self, *x):
730 self.value, self.direction, self.pattern, self.last_value, self.last_pattern = x + (self.value, self.pattern)
734 context.append(Context(value, direction, pattern, QSqlQuery(self.glb.db), None, None))
736 thread = Thread(self.FindThread, context[0])
737 thread.done.connect(lambda ids, t=thread, c=callback: self.FindDone(t, c, ids), Qt.QueuedConnection)
740 def FindDone(self, thread, callback, ids):
747 def __init__(self, glb, parent=None):
748 super(CallGraphModel, self).__init__(glb, parent)
750 def GetRoot(self):
751 return CallGraphRootItem(self.glb, self.params)
753 def columnCount(self, parent=None):
754 if self.params.have_ipc:
759 def columnHeader(self, column):
760 if self.params.have_ipc:
766 def columnAlignment(self, column):
767 if self.params.have_ipc:
773 def DoFindSelect(self, query, match):
783 def FindPath(self, query):
790 q2 = QSqlQuery(self.glb.db)
808 def __init__(self, glb, params, row, comm_id, thread_id, calls_id, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item):
809 super(CallTreeLevelTwoPlusItemBase, self).__init__(glb, params, row, parent_item)
810 self.comm_id = comm_id
811 self.thread_id = thread_id
812 self.calls_id = calls_id
813 self.call_time = call_time
814 self.time = time
815 self.insn_cnt = insn_cnt
816 self.cyc_cnt = cyc_cnt
817 self.branch_count = branch_count
819 def Select(self):
820 self.query_done = True
821 if self.calls_id == 0:
822 comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id)
825 if self.params.have_ipc:
829 query = QSqlQuery(self.glb.db)
835 " WHERE calls.parent_id = " + str(self.calls_id) + comm_thread +
838 if self.params.have_ipc:
846 child_item = CallTreeLevelThreeItem(self.glb, self.params, self.child_count, self.comm_id, self.thread_id, query.value(0), query.value(1), query.value(2), query.value(3), int(query.value(4)), insn_cnt, cyc_cnt, branch_count, self)
847 self.child_items.append(child_item)
848 self.child_count += 1
854 def __init__(self, glb, params, row, comm_id, thread_id, calls_id, name, dso, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item):
855 super(CallTreeLevelThreeItem, self).__init__(glb, params, row, comm_id, thread_id, calls_id, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item)
857 if self.params.have_ipc:
862 self.data = [ name, dso, str(call_time), str(time), PercentToOneDP(time, parent_item.time), str(insn_cnt), insn_pcnt, str(cyc_cnt), cyc_pcnt, ipc, str(branch_count), br_pcnt ]
864 self.data = [ name, dso, str(call_time), str(time), PercentToOneDP(time, parent_item.time), str(branch_count), PercentToOneDP(branch_count, parent_item.branch_count) ]
865 self.dbid = calls_id
871 def __init__(self, glb, params, row, comm_id, thread_id, pid, tid, parent_item):
872 super(CallTreeLevelTwoItem, self).__init__(glb, params, row, comm_id, thread_id, 0, 0, 0, 0, 0, 0, parent_item)
873 if self.params.have_ipc:
874 self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", "", "", "", "", "", ""]
876 self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", ""]
877 self.dbid = thread_id
879 def Select(self):
880 super(CallTreeLevelTwoItem, self).Select()
881 for child_item in self.child_items:
882 self.time += child_item.time
883 self.insn_cnt += child_item.insn_cnt
884 self.cyc_cnt += child_item.cyc_cnt
885 self.branch_count += child_item.branch_count
886 for child_item in self.child_items:
887 child_item.data[4] = PercentToOneDP(child_item.time, self.time)
888 if self.params.have_ipc:
889 child_item.data[6] = PercentToOneDP(child_item.insn_cnt, self.insn_cnt)
890 child_item.data[8] = PercentToOneDP(child_item.cyc_cnt, self.cyc_cnt)
891 child_item.data[11] = PercentToOneDP(child_item.branch_count, self.branch_count)
893 child_item.data[6] = PercentToOneDP(child_item.branch_count, self.branch_count)
899 def __init__(self, glb, params, row, comm_id, comm, parent_item):
900 super(CallTreeLevelOneItem, self).__init__(glb, params, row, parent_item)
901 if self.params.have_ipc:
902 self.data = [comm, "", "", "", "", "", "", "", "", "", "", ""]
904 self.data = [comm, "", "", "", "", "", ""]
905 self.dbid = comm_id
907 def Select(self):
908 self.query_done = True
909 query = QSqlQuery(self.glb.db)
913 " WHERE comm_id = " + str(self.dbid))
915 child_item = CallTreeLevelTwoItem(self.glb, self.params, self.child_count, self.dbid, query.value(0), query.value(1), query.value(2), self)
916 self.child_items.append(child_item)
917 self.child_count += 1
923 def __init__(self, glb, params):
924 super(CallTreeRootItem, self).__init__(glb, params, 0, None)
925 self.dbid = 0
926 self.query_done = True
935 child_item = CallTreeLevelOneItem(glb, params, self.child_count, query.value(0), query.value(1), self)
936 self.child_items.append(child_item)
937 self.child_count += 1
943 def __init__(self, glb, parent=None):
944 super(CallTreeModel, self).__init__(glb, parent)
946 def GetRoot(self):
947 return CallTreeRootItem(self.glb, self.params)
949 def columnCount(self, parent=None):
950 if self.params.have_ipc:
955 def columnHeader(self, column):
956 if self.params.have_ipc:
962 def columnAlignment(self, column):
963 if self.params.have_ipc:
969 def DoFindSelect(self, query, match):
978 def FindPath(self, query):
985 q2 = QSqlQuery(self.glb.db)
1000 def __init__(self, *children):
1001 super(HBoxLayout, self).__init__()
1003 self.layout().setContentsMargins(0, 0, 0, 0)
1006 self.layout().addWidget(child)
1008 self.layout().addLayout(child)
1014 def __init__(self, *children):
1015 super(VBoxLayout, self).__init__()
1017 self.layout().setContentsMargins(0, 0, 0, 0)
1020 self.layout().addWidget(child)
1022 self.layout().addLayout(child)
1028 def __init__(self, *children):
1029 self.vbox = QWidget()
1030 self.vbox.setLayout(VBoxLayout(*children))
1032 def Widget(self):
1033 return self.vbox
1039 def __init__(self, parent=None):
1040 super(TreeWindowBase, self).__init__(parent)
1042 self.model = None
1043 self.find_bar = None
1045 self.view = QTreeView()
1046 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
1047 self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
1049 self.context_menu = TreeContextMenu(self.view)
1051 def DisplayFound(self, ids):
1057 n = self.model.rowCount(parent)
1059 child = self.model.index(row, 0, parent)
1062 self.view.setExpanded(parent, True)
1063 self.view.setCurrentIndex(child)
1070 def Find(self, value, direction, pattern, context):
1071 self.view.setFocus()
1072 self.find_bar.Busy()
1073 self.model.Find(value, direction, pattern, context, self.FindDone)
1075 def FindDone(self, ids):
1077 if not self.DisplayFound(ids):
1079 self.find_bar.Idle()
1081 self.find_bar.NotFound()
1088 def __init__(self, glb, parent=None):
1089 super(CallGraphWindow, self).__init__(parent)
1091 self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x))
1093 self.view.setModel(self.model)
1096 self.view.setColumnWidth(c, w)
1098 self.find_bar = FindBar(self, self)
1100 self.vbox = VBox(self.view, self.find_bar.Widget())
1102 self.setWidget(self.vbox.Widget())
1104 AddSubWindow(glb.mainwindow.mdi_area, self, "Context-Sensitive Call Graph")
1110 def __init__(self, glb, parent=None, thread_at_time=None):
1111 super(CallTreeWindow, self).__init__(parent)
1113 self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x))
1115 self.view.setModel(self.model)
1118 self.view.setColumnWidth(c, w)
1120 self.find_bar = FindBar(self, self)
1122 self.vbox = VBox(self.view, self.find_bar.Widget())
1124 self.setWidget(self.vbox.Widget())
1126 AddSubWindow(glb.mainwindow.mdi_area, self, "Call Tree")
1129 self.DisplayThreadAtTime(*thread_at_time)
1131 def DisplayThreadAtTime(self, comm_id, thread_id, time):
1135 n = self.model.rowCount(parent)
1137 child = self.model.index(row, 0, parent)
1140 self.view.setExpanded(parent, True)
1141 self.view.setCurrentIndex(child)
1148 n = self.model.rowCount(parent)
1153 self.view.setExpanded(parent, True)
1154 child = self.model.index(row, 0, parent)
1159 self.view.setCurrentIndex(child)
1165 child = self.model.index(0, 0, parent)
1166 self.view.setExpanded(parent, True)
1167 self.view.setCurrentIndex(child)
1170 self.view.setExpanded(parent, True)
1171 self.view.setCurrentIndex(last_child)
1197 def __init__(self, x=0, y=0):
1198 self.x = x
1199 self.y = y
1201 def __str__(self):
1202 return "XY({}, {})".format(str(self.x), str(self.y))
1207 def __init__(self, lo=0, hi=0):
1208 self.lo = lo
1209 self.hi = hi
1211 def __str__(self):
1212 return "Subrange({}, {})".format(str(self.lo), str(self.hi))
1218 def __init__(self, key, title = "", ordinal = ""):
1219 self.key = key
1220 self.title = title
1221 self.ordinal = ordinal
1232 def __init__(self, colour):
1233 self.colour = colour
1239 def __init__(self, key, exec_comm_id, pid, tid, comm, thread_id, comm_id):
1240 super(SwitchGraphDataRegion, self).__init__(key)
1242 self.title = str(pid) + " / " + str(tid) + " " + comm
1244 self.ordinal = str(pid).rjust(16) + str(exec_comm_id).rjust(8) + str(tid).rjust(16)
1245 self.exec_comm_id = exec_comm_id
1246 self.pid = pid
1247 self.tid = tid
1248 self.comm = comm
1249 self.thread_id = thread_id
1250 self.comm_id = comm_id
1256 def __init__(self, data, index, x, y, altx=None, alty=None, hregion=None, vregion=None):
1257 self.data = data
1258 self.index = index
1259 self.x = x
1260 self.y = y
1261 self.altx = altx
1262 self.alty = alty
1263 self.hregion = hregion
1264 self.vregion = vregion
1270 def __init__(self, collection, xbase=Decimal(0), ybase=Decimal(0)):
1271 self.collection = collection
1272 self.points = []
1273 self.xbase = xbase
1274 self.ybase = ybase
1275 self.title = ""
1277 def AddPoint(self, x, y, altx=None, alty=None, hregion=None, vregion=None):
1278 index = len(self.points)
1280 x = float(Decimal(x) - self.xbase)
1281 y = float(Decimal(y) - self.ybase)
1283 self.points.append(GraphDataPoint(self, index, x, y, altx, alty, hregion, vregion))
1285 def XToData(self, x):
1286 return Decimal(x) + self.xbase
1288 def YToData(self, y):
1289 return Decimal(y) + self.ybase
1295 def __init__(self, db, collection, cpu, xbase):
1296 super(SwitchGraphData, self).__init__(collection, xbase)
1298 self.cpu = cpu
1299 self.title = "CPU " + str(cpu)
1300 self.SelectSwitches(db)
1302 def SelectComms(self, db, thread_id, last_comm_id, start_time, end_time):
1307 " AND exec_flag = " + self.collection.glb.dbref.TRUE +
1316 hregion = self.HRegion(db, thread_id, comm_id, time)
1317 self.AddPoint(time, 1000, None, None, hregion)
1319 def SelectSwitches(self, db):
1326 " WHERE machine_id = " + str(self.collection.machine_id) +
1327 " AND cpu = " + str(self.cpu) +
1334 self.SelectComms(db, last_thread_id, last_comm_id, last_time, query.value(0))
1337 if len(self.points) == 0:
1338 start_time = self.collection.glb.StartTime(self.collection.machine_id)
1339 hregion = self.HRegion(db, query.value(1), query.value(3), start_time)
1340 self.AddPoint(start_time, 1000, None, None, hregion)
1344 hregion = self.HRegion(db, thread_id, comm_id, time)
1345 self.AddPoint(time, 1000, None, None, hregion)
1350 def NewHRegion(self, db, key, thread_id, comm_id, time):
1368 def HRegion(self, db, thread_id, comm_id, time):
1370 hregion = self.collection.LookupHRegion(key)
1372 hregion = self.NewHRegion(db, key, thread_id, comm_id, time)
1373 self.collection.AddHRegion(key, hregion)
1380 def __init__(self, glb):
1381 self.glb = glb
1382 self.data = []
1383 self.hregions = {}
1384 self.xrangelo = None
1385 self.xrangehi = None
1386 self.yrangelo = None
1387 self.yrangehi = None
1388 self.dp = XY(0, 0)
1390 def AddGraphData(self, data):
1391 self.data.append(data)
1393 def LookupHRegion(self, key):
1394 if key in self.hregions:
1395 return self.hregions[key]
1398 def AddHRegion(self, key, hregion):
1399 self.hregions[key] = hregion
1405 def __init__(self, glb, db, machine_id):
1406 super(SwitchGraphDataCollection, self).__init__(glb)
1408 self.machine_id = machine_id
1409 self.cpus = self.SelectCPUs(db)
1411 self.xrangelo = glb.StartTime(machine_id)
1412 self.xrangehi = glb.FinishTime(machine_id)
1414 self.yrangelo = Decimal(0)
1415 self.yrangehi = Decimal(1000)
1417 for cpu in self.cpus:
1418 self.AddGraphData(SwitchGraphData(db, self, cpu, self.xrangelo))
1420 def SelectCPUs(self, db):
1425 " WHERE machine_id = " + str(self.machine_id))
1434 def __init__(self, data, graph_width, graph_height, attrs, event_handler, parent=None):
1435 super(SwitchGraphDataGraphicsItem, self).__init__(parent)
1437 self.data = data
1438 self.graph_width = graph_width
1439 self.graph_height = graph_height
1440 self.attrs = attrs
1441 self.event_handler = event_handler
1442 self.setAcceptHoverEvents(True)
1444 def boundingRect(self):
1445 return QRectF(0, 0, self.graph_width, self.graph_height)
1447 def PaintPoint(self, painter, last, x):
1448 if not(last is None or last.hregion.pid == 0 or x < self.attrs.subrange.x.lo):
1449 if last.x < self.attrs.subrange.x.lo:
1450 x0 = self.attrs.subrange.x.lo
1453 if x > self.attrs.subrange.x.hi:
1454 x1 = self.attrs.subrange.x.hi
1457 x0 = self.attrs.XToPixel(x0)
1458 x1 = self.attrs.XToPixel(x1)
1460 y0 = self.attrs.YToPixel(last.y)
1462 colour = self.attrs.region_attributes[last.hregion.key].colour
1467 painter.drawLine(x0, self.graph_height - y0, x0, self.graph_height)
1469 painter.fillRect(x0, self.graph_height - y0, width, self.graph_height - 1, colour)
1471 def paint(self, painter, option, widget):
1473 for point in self.data.points:
1474 self.PaintPoint(painter, last, point.x)
1475 if point.x > self.attrs.subrange.x.hi:
1478 self.PaintPoint(painter, last, self.attrs.subrange.x.hi + 1)
1480 def BinarySearchPoint(self, target):
1482 higher_pos = len(self.data.points)
1485 val = self.data.points[pos].x
1493 def XPixelToData(self, x):
1494 x = self.attrs.PixelToX(x)
1495 if x < self.data.points[0].x:
1500 pos = self.BinarySearchPoint(x)
1502 return (low, pos, self.data.XToData(x))
1504 def EventToData(self, event):
1506 if len(self.data.points) < 1:
1511 low0, pos0, time_from = self.XPixelToData(x)
1512 low1, pos1, time_to = self.XPixelToData(x + 1)
1517 hregion = self.data.points[i].hregion
1522 time = self.data.XToData(self.data.points[i].x)
1526 def hoverMoveEvent(self, event):
1527 time_from, time_to, hregions, hregion_times = self.EventToData(event)
1529 self.event_handler.PointEvent(self.data.cpu, time_from, time_to, hregions)
1531 def hoverLeaveEvent(self, event):
1532 self.event_handler.NoPointEvent()
1534 def mousePressEvent(self, event):
1536 super(SwitchGraphDataGraphicsItem, self).mousePressEvent(event)
1538 time_from, time_to, hregions, hregion_times = self.EventToData(event)
1540 self.event_handler.RightClickEvent(self.data.cpu, hregion_times, event.screenPos())
1546 def __init__(self, width, parent=None):
1547 super(XAxisGraphicsItem, self).__init__(parent)
1549 self.width = width
1550 self.max_mark_sz = 4
1551 self.height = self.max_mark_sz + 1
1553 def boundingRect(self):
1554 return QRectF(0, 0, self.width, self.height)
1556 def Step(self):
1557 attrs = self.parentItem().attrs
1560 s = (3.0 * t) / self.width
1566 def PaintMarks(self, painter, at_y, lo, hi, step, i):
1567 attrs = self.parentItem().attrs
1577 sz = self.max_mark_sz
1583 def paint(self, painter, option, widget):
1585 painter.drawLine(0, 0, self.width - 1, 0)
1586 n = self.Step()
1587 attrs = self.parentItem().attrs
1595 self.PaintMarks(painter, 0, x, subrange.hi, n, i)
1597 def ScaleDimensions(self):
1598 n = self.Step()
1599 attrs = self.parentItem().attrs
1607 def PaintScale(self, painter, at_x, at_y):
1608 n, lo, hi, width = self.ScaleDimensions()
1612 self.PaintMarks(painter, at_y, lo, hi, n, 0)
1614 def ScaleWidth(self):
1615 n, lo, hi, width = self.ScaleDimensions()
1618 def ScaleHeight(self):
1619 return self.height
1621 def ScaleUnit(self):
1622 return self.Step() * 10
1628 def __init__(self, axis, parent=None):
1629 super(ScaleGraphicsItem, self).__init__(parent)
1630 self.axis = axis
1632 def boundingRect(self):
1633 scale_width = self.axis.ScaleWidth()
1636 return QRectF(0, 0, self.axis.ScaleWidth() + 100, self.axis.ScaleHeight())
1638 def paint(self, painter, option, widget):
1639 scale_width = self.axis.ScaleWidth()
1642 self.axis.PaintScale(painter, 0, 5)
1644 painter.drawText(QPointF(x, 10), self.Text())
1646 def Unit(self):
1647 return self.axis.ScaleUnit()
1649 def Text(self):
1656 def __init__(self, axis, parent=None):
1657 super(SwitchScaleGraphicsItem, self).__init__(axis, parent)
1659 def Text(self):
1660 unit = self.Unit()
1679 def __init__(self, collection, data, attrs, event_handler, first, parent=None):
1680 super(SwitchGraphGraphicsItem, self).__init__(parent)
1681 self.collection = collection
1682 self.data = data
1683 self.attrs = attrs
1684 self.event_handler = event_handler
1689 self.title_graphics = QGraphicsSimpleTextItem(data.title, self)
1691 self.title_graphics.setPos(margin, margin)
1695 self.graph_origin_x = margin + title_width + margin
1696 self.graph_origin_y = graph_height + margin
1700 self.yline = QGraphicsLineItem(0, 0, 0, graph_height, self)
1702 self.x_axis = XAxisGraphicsItem(graph_width, self)
1703 self.x_axis.setPos(self.graph_origin_x, self.graph_origin_y + 1)
1706 self.scale_item = SwitchScaleGraphicsItem(self.x_axis, self)
1707 self.scale_item.setPos(self.graph_origin_x, self.graph_origin_y + 10)
1709 self.yline.setPos(self.graph_origin_x - y_axis_size, self.graph_origin_y - graph_height)
1711 self.axis_point = QGraphicsLineItem(0, 0, 0, 0, self)
1712 self.axis_point.setPos(self.graph_origin_x - 1, self.graph_origin_y +1)
1714 self.width = self.graph_origin_x + graph_width + margin
1715 self.height = self.graph_origin_y + margin
1717 self.graph = SwitchGraphDataGraphicsItem(data, graph_width, graph_height, attrs, event_handler, self)
1718 self.graph.setPos(self.graph_origin_x, self.graph_origin_y - graph_height)
1721 parent.EnableRubberBand(self.graph_origin_x, self.graph_origin_x + graph_width - 1, self)
1723 def boundingRect(self):
1724 return QRectF(0, 0, self.width, self.height)
1726 def paint(self, painter, option, widget):
1729 def RBXToPixel(self, x):
1730 return self.attrs.PixelToX(x - self.graph_origin_x)
1732 def RBXRangeToPixel(self, x0, x1):
1733 return (self.RBXToPixel(x0), self.RBXToPixel(x1 + 1))
1735 def RBPixelToTime(self, x):
1736 if x < self.data.points[0].x:
1737 return self.data.XToData(0)
1738 return self.data.XToData(x)
1740 def RBEventTimes(self, x0, x1):
1741 x0, x1 = self.RBXRangeToPixel(x0, x1)
1742 time_from = self.RBPixelToTime(x0)
1743 time_to = self.RBPixelToTime(x1)
1746 def RBEvent(self, x0, x1):
1747 time_from, time_to = self.RBEventTimes(x0, x1)
1748 self.event_handler.RangeEvent(time_from, time_to)
1750 def RBMoveEvent(self, x0, x1):
1753 self.RBEvent(x0, x1)
1755 def RBReleaseEvent(self, x0, x1, selection_state):
1758 x0, x1 = self.RBXRangeToPixel(x0, x1)
1759 self.event_handler.SelectEvent(x0, x1, selection_state)
1765 def __init__(self, parent=None):
1766 super(VerticalBracketGraphicsItem, self).__init__(parent)
1768 self.width = 0
1769 self.height = 0
1770 self.hide()
1772 def SetSize(self, width, height):
1773 self.width = width + 1
1774 self.height = height + 1
1776 def boundingRect(self):
1777 return QRectF(0, 0, self.width, self.height)
1779 def paint(self, painter, option, widget):
1781 painter.fillRect(0, 0, self.width, self.height, colour)
1782 x1 = self.width - 1
1783 y1 = self.height - 1
1795 def __init__(self, collection, attrs, event_handler, child_class, parent=None):
1796 super(VertcalGraphSetGraphicsItem, self).__init__(parent)
1798 self.collection = collection
1800 self.top = 10
1802 self.width = 0
1803 self.height = self.top
1805 self.rubber_band = None
1806 self.rb_enabled = False
1810 child = child_class(collection, data, attrs, event_handler, first, self)
1811 child.setPos(0, self.height + 1)
1813 if rect.right() > self.width:
1814 self.width = rect.right()
1815 self.height = self.height + rect.bottom() + 1
1818 self.bracket = VerticalBracketGraphicsItem(self)
1820 def EnableRubberBand(self, xlo, xhi, rb_event_handler):
1821 if self.rb_enabled:
1823 self.rb_enabled = True
1824 self.rb_in_view = False
1825 self.setAcceptedMouseButtons(Qt.LeftButton)
1826 self.rb_xlo = xlo
1827 self.rb_xhi = xhi
1828 self.rb_event_handler = rb_event_handler
1829 self.mousePressEvent = self.MousePressEvent
1830 self.mouseMoveEvent = self.MouseMoveEvent
1831 self.mouseReleaseEvent = self.MouseReleaseEvent
1833 def boundingRect(self):
1834 return QRectF(0, 0, self.width, self.height)
1836 def paint(self, painter, option, widget):
1839 def RubberBandParent(self):
1840 scene = self.scene()
1845 def RubberBandSetGeometry(self, rect):
1846 scene_rectf = self.mapRectToScene(QRectF(rect))
1847 scene = self.scene()
1850 self.rubber_band.setGeometry(poly.boundingRect())
1852 def SetSelection(self, selection_state):
1853 if self.rubber_band:
1855 self.RubberBandSetGeometry(selection_state)
1856 self.rubber_band.show()
1858 self.rubber_band.hide()
1860 def SetBracket(self, rect):
1863 self.bracket.setPos(x, y)
1864 self.bracket.SetSize(width, height)
1865 self.bracket.show()
1867 self.bracket.hide()
1869 def RubberBandX(self, event):
1871 if x < self.rb_xlo:
1872 x = self.rb_xlo
1873 elif x > self.rb_xhi:
1874 x = self.rb_xhi
1876 self.rb_in_view = True
1879 def RubberBandRect(self, x):
1880 if self.rb_origin.x() <= x:
1881 width = x - self.rb_origin.x()
1882 rect = QRect(self.rb_origin, QSize(width, self.height))
1884 width = self.rb_origin.x() - x
1885 top_left = QPoint(self.rb_origin.x() - width, self.rb_origin.y())
1886 rect = QRect(top_left, QSize(width, self.height))
1889 def MousePressEvent(self, event):
1890 self.rb_in_view = False
1891 x = self.RubberBandX(event)
1892 self.rb_origin = QPoint(x, self.top)
1893 if self.rubber_band is None:
1894 self.rubber_band = QRubberBand(QRubberBand.Rectangle, self.RubberBandParent())
1895 self.RubberBandSetGeometry(QRect(self.rb_origin, QSize(0, self.height)))
1896 if self.rb_in_view:
1897 self.rubber_band.show()
1898 self.rb_event_handler.RBMoveEvent(x, x)
1900 self.rubber_band.hide()
1902 def MouseMoveEvent(self, event):
1903 x = self.RubberBandX(event)
1904 rect = self.RubberBandRect(x)
1905 self.RubberBandSetGeometry(rect)
1906 if self.rb_in_view:
1907 self.rubber_band.show()
1908 self.rb_event_handler.RBMoveEvent(self.rb_origin.x(), x)
1910 def MouseReleaseEvent(self, event):
1911 x = self.RubberBandX(event)
1912 if self.rb_in_view:
1913 selection_state = self.RubberBandRect(x)
1916 self.rb_event_handler.RBReleaseEvent(self.rb_origin.x(), x, selection_state)
1922 def __init__(self, collection, region_attributes, parent=None):
1923 super(SwitchGraphLegendModel, self).__init__(parent)
1925 self.region_attributes = region_attributes
1927 self.child_items = sorted(collection.hregions.values(), key=GraphDataRegionOrdinal)
1928 self.child_count = len(self.child_items)
1930 self.highlight_set = set()
1932 self.column_headers = ("pid", "tid", "comm")
1934 def rowCount(self, parent):
1935 return self.child_count
1937 def headerData(self, section, orientation, role):
1942 return self.columnHeader(section)
1944 def index(self, row, column, parent):
1945 return self.createIndex(row, column, self.child_items[row])
1947 def columnCount(self, parent=None):
1948 return len(self.column_headers)
1950 def columnHeader(self, column):
1951 return self.column_headers[column]
1953 def data(self, index, role):
1955 child = self.child_items[index.row()]
1956 if child in self.highlight_set:
1957 return self.region_attributes[child.key].colour
1960 child = self.child_items[index.row()]
1961 if child in self.highlight_set:
1963 return self.region_attributes[child.key].colour
1966 hregion = self.child_items[index.row()]
1976 def SetHighlight(self, row, set_highlight):
1977 child = self.child_items[row]
1978 top_left = self.createIndex(row, 0, child)
1979 bottom_right = self.createIndex(row, len(self.column_headers) - 1, child)
1980 self.dataChanged.emit(top_left, bottom_right)
1982 def Highlight(self, highlight_set):
1983 for row in xrange(self.child_count):
1984 child = self.child_items[row]
1985 if child in self.highlight_set:
1987 self.SetHighlight(row, False)
1989 self.SetHighlight(row, True)
1990 self.highlight_set = highlight_set
1996 def __init__(self, collection, region_attributes, parent=None):
1997 super(SwitchGraphLegend, self).__init__(parent)
1999 self.data_model = SwitchGraphLegendModel(collection, region_attributes)
2001 self.model = QSortFilterProxyModel()
2002 self.model.setSourceModel(self.data_model)
2004 self.view = QTableView()
2005 self.view.setModel(self.model)
2006 self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
2007 self.view.verticalHeader().setVisible(False)
2008 self.view.sortByColumn(-1, Qt.AscendingOrder)
2009 self.view.setSortingEnabled(True)
2010 self.view.resizeColumnsToContents()
2011 self.view.resizeRowsToContents()
2013 self.vbox = VBoxLayout(self.view)
2014 self.setLayout(self.vbox)
2016 sz1 = self.view.columnWidth(0) + self.view.columnWidth(1) + self.view.columnWidth(2) + 2
2017 sz1 = sz1 + self.view.verticalScrollBar().sizeHint().width()
2018 self.saved_size = sz1
2020 def resizeEvent(self, event):
2021 self.saved_size = self.size().width()
2022 super(SwitchGraphLegend, self).resizeEvent(event)
2024 def Highlight(self, highlight_set):
2025 self.data_model.Highlight(highlight_set)
2026 self.update()
2028 def changeEvent(self, event):
2030 self.view.resizeRowsToContents()
2031 self.view.resizeColumnsToContents()
2033 self.view.resizeRowsToContents()
2034 super(SwitchGraphLegend, self).changeEvent(event)
2080 def __init__(self, scale, subrange, region_attributes, dp):
2081 self.scale = scale
2082 self.subrange = subrange
2083 self.region_attributes = region_attributes
2085 self.dp = dp # data decimal places
2086 self.Update()
2088 def XToPixel(self, x):
2089 return int(round((x - self.subrange.x.lo) * self.scale.x, self.pdp.x))
2091 def YToPixel(self, y):
2092 return int(round((y - self.subrange.y.lo) * self.scale.y, self.pdp.y))
2094 def PixelToXRounded(self, px):
2095 return round((round(px, 0) / self.scale.x), self.dp.x) + self.subrange.x.lo
2097 def PixelToYRounded(self, py):
2098 return round((round(py, 0) / self.scale.y), self.dp.y) + self.subrange.y.lo
2100 def PixelToX(self, px):
2101 x = self.PixelToXRounded(px)
2102 if self.pdp.x == 0:
2103 rt = self.XToPixel(x)
2108 def PixelToY(self, py):
2109 y = self.PixelToYRounded(py)
2110 if self.pdp.y == 0:
2111 rt = self.YToPixel(y)
2116 def ToPDP(self, dp, scale):
2132 def Update(self):
2133 x = self.ToPDP(self.dp.x, self.scale.x)
2134 y = self.ToPDP(self.dp.y, self.scale.y)
2135 self.pdp = XY(x, y) # pixel decimal places
2141 def __init__(self, parent=None):
2142 super(SwitchGraphSplitter, self).__init__(parent)
2144 self.first_time = False
2146 def resizeEvent(self, ev):
2147 if self.first_time:
2148 self.first_time = False
2149 sz1 = self.widget(1).view.columnWidth(0) + self.widget(1).view.columnWidth(1) + self.widget(1).view.columnWidth(2) + 2
2150 sz1 = sz1 + self.widget(1).view.verticalScrollBar().sizeHint().width()
2151 sz0 = self.size().width() - self.handleWidth() - sz1
2152 self.setSizes([sz0, sz1])
2153 elif not(self.widget(1).saved_size is None):
2154 sz1 = self.widget(1).saved_size
2155 sz0 = self.size().width() - self.handleWidth() - sz1
2156 self.setSizes([sz0, sz1])
2157 super(SwitchGraphSplitter, self).resizeEvent(ev)
2165 def __init__(self, parent=None):
2166 super(GraphWidget, self).__init__(parent)
2168 def GraphTitleChanged(self, title):
2169 self.graph_title_changed.emit(title)
2171 def Title(self):
2190 def __init__(self, glb, collection, parent=None):
2191 super(SwitchGraphWidget, self).__init__(parent)
2193 self.glb = glb
2194 self.collection = collection
2196 self.back_state = []
2197 self.forward_state = []
2198 self.selection_state = (None, None)
2199 self.fwd_rect = None
2200 self.start_time = self.glb.StartTime(collection.machine_id)
2218 scale = self.GetScaleForRange(subrange)
2220 self.attrs = GraphAttributes(scale, subrange, region_attributes, collection.dp)
2222 self.item = VertcalGraphSetGraphicsItem(collection, self.attrs, self, SwitchGraphGraphicsItem)
2224 self.scene = QGraphicsScene()
2225 self.scene.addItem(self.item)
2227 self.view = QGraphicsView(self.scene)
2228 self.view.centerOn(0, 0)
2229 self.view.setAlignment(Qt.AlignLeft | Qt.AlignTop)
2231 self.legend = SwitchGraphLegend(collection, region_attributes)
2233 self.splitter = SwitchGraphSplitter()
2234 self.splitter.addWidget(self.view)
2235 self.splitter.addWidget(self.legend)
2237 self.point_label = QLabel("")
2238 self.point_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
2240 self.back_button = QToolButton()
2241 self.back_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowLeft))
2242 self.back_button.setDisabled(True)
2243 self.back_button.released.connect(lambda: self.Back())
2245 self.forward_button = QToolButton()
2246 self.forward_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowRight))
2247 self.forward_button.setDisabled(True)
2248 self.forward_button.released.connect(lambda: self.Forward())
2250 self.zoom_button = QToolButton()
2251 self.zoom_button.setText("Zoom")
2252 self.zoom_button.setDisabled(True)
2253 self.zoom_button.released.connect(lambda: self.Zoom())
2255 self.hbox = HBoxLayout(self.back_button, self.forward_button, self.zoom_button, self.point_label)
2257 self.vbox = VBoxLayout(self.splitter, self.hbox)
2259 self.setLayout(self.vbox)
2261 def GetScaleForRangeX(self, xsubrange):
2267 def GetScaleForRangeY(self, ysubrange):
2273 def GetScaleForRange(self, subrange):
2275 xscale = self.GetScaleForRangeX(subrange.x)
2276 yscale = self.GetScaleForRangeY(subrange.y)
2279 def PointEvent(self, cpu, time_from, time_to, hregions):
2282 rel_time_from = time_from - self.glb.StartTime(self.collection.machine_id)
2284 self.point_label.setText(text)
2285 self.legend.Highlight(hregions)
2287 def RightClickEvent(self, cpu, hregion_times, pos):
2288 if not IsSelectable(self.glb.db, "calls", "WHERE parent_id >= 0"):
2290 menu = QMenu(self.view)
2294 menu.addAction(CreateAction(menu_text, "Show Call Tree", lambda a=None, args=thread_at_time: self.RightClickSelect(args), self.view))
2297 def RightClickSelect(self, args):
2298 CallTreeWindow(self.glb, self.glb.mainwindow, thread_at_time=args)
2300 def NoPointEvent(self):
2301 self.point_label.setText("")
2302 self.legend.Highlight({})
2304 def RangeEvent(self, time_from, time_to):
2308 self.point_label.setText("")
2310 rel_time_from = time_from - self.start_time
2311 rel_time_to = time_to - self.start_time
2314 self.point_label.setText(text)
2316 def BackState(self):
2317 return (self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect)
2319 def PushBackState(self):
2320 state = copy.deepcopy(self.BackState())
2321 self.back_state.append(state)
2322 self.back_button.setEnabled(True)
2324 def PopBackState(self):
2325 self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect = self.back_state.pop()
2326 self.attrs.Update()
2327 if not self.back_state:
2328 self.back_button.setDisabled(True)
2330 def PushForwardState(self):
2331 state = copy.deepcopy(self.BackState())
2332 self.forward_state.append(state)
2333 self.forward_button.setEnabled(True)
2335 def PopForwardState(self):
2336 self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect = self.forward_state.pop()
2337 self.attrs.Update()
2338 if not self.forward_state:
2339 self.forward_button.setDisabled(True)
2341 def Title(self):
2342 time_from = self.collection.xrangelo + Decimal(self.attrs.subrange.x.lo)
2343 time_to = self.collection.xrangelo + Decimal(self.attrs.subrange.x.hi)
2344 rel_time_from = time_from - self.start_time
2345 rel_time_to = time_to - self.start_time
2350 def Update(self):
2351 selected_subrange, selection_state = self.selection_state
2352 self.item.SetSelection(selection_state)
2353 self.item.SetBracket(self.fwd_rect)
2354 self.zoom_button.setDisabled(selected_subrange is None)
2355 self.GraphTitleChanged(self.Title())
2356 self.item.update(self.item.boundingRect())
2358 def Back(self):
2359 if not self.back_state:
2361 self.PushForwardState()
2362 self.PopBackState()
2363 self.Update()
2365 def Forward(self):
2366 if not self.forward_state:
2368 self.PushBackState()
2369 self.PopForwardState()
2370 self.Update()
2372 def SelectEvent(self, x0, x1, selection_state):
2379 self.selection_state = (selected_subrange, selection_state)
2380 self.zoom_button.setDisabled(selected_subrange is None)
2382 def Zoom(self):
2383 selected_subrange, selection_state = self.selection_state
2386 self.fwd_rect = selection_state
2387 self.item.SetSelection(None)
2388 self.PushBackState()
2389 self.attrs.subrange.x = selected_subrange
2390 self.forward_state = []
2391 self.forward_button.setDisabled(True)
2392 self.selection_state = (None, None)
2393 self.fwd_rect = None
2394 self.attrs.scale.x = self.GetScaleForRangeX(self.attrs.subrange.x)
2395 self.attrs.Update()
2396 self.Update()
2402 def __init__(self, glb, title, init_fn):
2403 self.init_fn = init_fn
2404 self.done = False
2405 self.result = None
2407 self.msg_box = QMessageBox(glb.mainwindow)
2408 self.msg_box.setText("Initializing " + title + ". Please wait.")
2409 self.msg_box.setWindowTitle("Initializing " + title)
2410 self.msg_box.setWindowIcon(glb.mainwindow.style().standardIcon(QStyle.SP_MessageBoxInformation))
2412 self.init_thread = Thread(self.ThreadFn, glb)
2413 self.init_thread.done.connect(lambda: self.Done(), Qt.QueuedConnection)
2415 self.init_thread.start()
2417 def Done(self):
2418 self.msg_box.done(0)
2420 def ThreadFn(self, glb):
2423 self.result = self.init_fn(db)
2424 self.done = True
2427 def Result(self):
2428 while not self.done:
2429 self.msg_box.exec_()
2430 self.init_thread.wait()
2431 return self.result
2441 def __init__(self, glb, parent=None):
2442 super(TimeChartByCPUWindow, self).__init__(parent)
2444 self.glb = glb
2445 self.machine_id = glb.HostMachineId()
2446 self.collection_name = "SwitchGraphDataCollection " + str(self.machine_id)
2448 collection = LookupModel(self.collection_name)
2450 collection = SlowInit(glb, "Time Chart", self.Init)
2452 self.widget = SwitchGraphWidget(glb, collection, self)
2453 self.view = self.widget
2455 self.base_title = "Time Chart by CPU"
2456 self.setWindowTitle(self.base_title + self.widget.Title())
2457 self.widget.graph_title_changed.connect(self.GraphTitleChanged)
2459 self.setWidget(self.widget)
2461 AddSubWindow(glb.mainwindow.mdi_area, self, self.windowTitle())
2463 def Init(self, db):
2464 return LookupCreateModel(self.collection_name, lambda : SwitchGraphDataCollection(self.glb, db, self.machine_id))
2466 def GraphTitleChanged(self, title):
2467 self.setWindowTitle(self.base_title + " : " + title)
2473 def __init__(self, root):
2474 self.root = root
2475 self.value, self.direction, self.pattern, self.last_value, self.last_pattern = (None,) * 5
2476 self.rows = []
2477 self.pos = 0
2479 def FindSelect(self):
2480 self.rows = []
2481 if self.pattern:
2482 pattern = re.compile(self.value)
2483 for child in self.root.child_items:
2486 self.rows.append(child.row)
2489 for child in self.root.child_items:
2491 if self.value in str(column_data):
2492 self.rows.append(child.row)
2495 def FindValue(self):
2496 self.pos = 0
2497 if self.last_value != self.value or self.pattern != self.last_pattern:
2498 self.FindSelect()
2499 if not len(self.rows):
2501 return self.rows[self.pos]
2503 def FindThread(self):
2504 if self.direction == 0 or self.value != self.last_value or self.pattern != self.last_pattern:
2505 row = self.FindValue()
2506 elif len(self.rows):
2507 if self.direction > 0:
2508 self.pos += 1
2509 if self.pos >= len(self.rows):
2510 self.pos = 0
2512 self.pos -= 1
2513 if self.pos < 0:
2514 self.pos = len(self.rows) - 1
2515 row = self.rows[self.pos]
2520 def Find(self, value, direction, pattern, context, callback):
2521 self.value, self.direction, self.pattern, self.last_value, self.last_pattern = (value, direction,pattern, self.value, self.pattern)
2523 thread = Thread(self.FindThread)
2524 thread.done.connect(lambda row, t=thread, c=callback: self.FindDone(t, c, row), Qt.QueuedConnection)
2527 def FindDone(self, thread, callback, row):
2538 def __init__(self, dbref, sql, buffer, head, tail, fetch_count, fetching_done, process_target, wait_event, fetched_event, prep):
2541 self.db, dbname = dbref.Open(conn_name)
2542 self.sql = sql
2543 self.buffer = buffer
2544 self.head = head
2545 self.tail = tail
2546 self.fetch_count = fetch_count
2547 self.fetching_done = fetching_done
2548 self.process_target = process_target
2549 self.wait_event = wait_event
2550 self.fetched_event = fetched_event
2551 self.prep = prep
2552 self.query = QSqlQuery(self.db)
2553 self.query_limit = 0 if "$$last_id$$" in sql else 2
2554 self.last_id = -1
2555 self.fetched = 0
2556 self.more = True
2557 self.local_head = self.head.value
2558 self.local_tail = self.tail.value
2560 def Select(self):
2561 if self.query_limit:
2562 if self.query_limit == 1:
2564 self.query_limit -= 1
2565 stmt = self.sql.replace("$$last_id$$", str(self.last_id))
2566 QueryExec(self.query, stmt)
2568 def Next(self):
2569 if not self.query.next():
2570 self.Select()
2571 if not self.query.next():
2573 self.last_id = self.query.value(0)
2574 return self.prep(self.query)
2576 def WaitForTarget(self):
2578 self.wait_event.clear()
2579 target = self.process_target.value
2580 if target > self.fetched or target < 0:
2582 self.wait_event.wait()
2585 def HasSpace(self, sz):
2586 if self.local_tail <= self.local_head:
2587 space = len(self.buffer) - self.local_head
2593 self.buffer[self.local_head : self.local_head + len(nd)] = nd
2594 self.local_head = 0
2595 if self.local_tail - self.local_head > sz:
2599 def WaitForSpace(self, sz):
2600 if self.HasSpace(sz):
2603 self.wait_event.clear()
2604 self.local_tail = self.tail.value
2605 if self.HasSpace(sz):
2607 self.wait_event.wait()
2609 def AddToBuffer(self, obj):
2614 self.WaitForSpace(sz)
2615 pos = self.local_head
2616 self.buffer[pos : pos + len(nd)] = nd
2617 self.buffer[pos + glb_nsz : pos + sz] = d
2618 self.local_head += sz
2620 def FetchBatch(self, batch_size):
2623 obj = self.Next()
2625 self.more = False
2627 self.AddToBuffer(obj)
2630 self.fetched += fetched
2631 with self.fetch_count.get_lock():
2632 self.fetch_count.value += fetched
2633 self.head.value = self.local_head
2634 self.fetched_event.set()
2636 def Run(self):
2637 while self.more:
2638 target = self.WaitForTarget()
2641 batch_size = min(glb_chunk_sz, target - self.fetched)
2642 self.FetchBatch(batch_size)
2643 self.fetching_done.value = True
2644 self.fetched_event.set()
2656 def __init__(self, glb, sql, prep, process_data, parent=None):
2657 super(SQLFetcher, self).__init__(parent)
2658 self.process_data = process_data
2659 self.more = True
2660 self.target = 0
2661 self.last_target = 0
2662 self.fetched = 0
2663 self.buffer_size = 16 * 1024 * 1024
2664 self.buffer = Array(c_char, self.buffer_size, lock=False)
2665 self.head = Value(c_longlong)
2666 self.tail = Value(c_longlong)
2667 self.local_tail = 0
2668 self.fetch_count = Value(c_longlong)
2669 self.fetching_done = Value(c_bool)
2670 self.last_count = 0
2671 self.process_target = Value(c_longlong)
2672 self.wait_event = Event()
2673 self.fetched_event = Event()
2674 glb.AddInstanceToShutdownOnExit(self)
2675 self.process = Process(target=SQLFetcherFn, args=(glb.dbref, sql, self.buffer, self.head, self.tail, self.fetch_count, self.fetching_done, self.process_target, self.wait_event, self.fetched_event, prep))
2676 self.process.start()
2677 self.thread = Thread(self.Thread)
2678 self.thread.done.connect(self.ProcessData, Qt.QueuedConnection)
2679 self.thread.start()
2681 def Shutdown(self):
2683 self.process_target.value = -1
2684 self.wait_event.set()
2685 self.more = False
2686 self.fetching_done.value = True
2687 self.fetched_event.set()
2689 def Thread(self):
2690 if not self.more:
2693 self.fetched_event.clear()
2694 fetch_count = self.fetch_count.value
2695 if fetch_count != self.last_count:
2697 if self.fetching_done.value:
2698 self.more = False
2700 self.fetched_event.wait()
2701 count = fetch_count - self.last_count
2702 self.last_count = fetch_count
2703 self.fetched += count
2706 def Fetch(self, nr):
2707 if not self.more:
2710 result = self.fetched
2711 extra = result + nr - self.target
2713 self.target += extra
2715 if self.process_target.value >= 0:
2716 self.process_target.value = self.target
2717 self.wait_event.set()
2720 def RemoveFromBuffer(self):
2721 pos = self.local_tail
2722 if len(self.buffer) - pos < glb_nsz:
2724 n = pickle.loads(self.buffer[pos : pos + glb_nsz])
2727 n = pickle.loads(self.buffer[0 : glb_nsz])
2729 obj = pickle.loads(self.buffer[pos : pos + n])
2730 self.local_tail = pos + n
2733 def ProcessData(self, count):
2735 obj = self.RemoveFromBuffer()
2736 self.process_data(obj)
2737 self.tail.value = self.local_tail
2738 self.wait_event.set()
2739 self.done.emit(count)
2745 def __init__(self, model, parent):
2746 self.model = model
2748 self.label = QLabel("Number of records (x " + "{:,}".format(glb_chunk_sz) + ") to fetch:")
2749 self.label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
2751 self.fetch_count = QSpinBox()
2752 self.fetch_count.setRange(1, 1000000)
2753 self.fetch_count.setValue(10)
2754 self.fetch_count.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
2756 self.fetch = QPushButton("Go!")
2757 self.fetch.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
2758 self.fetch.released.connect(self.FetchMoreRecords)
2760 self.progress = QProgressBar()
2761 self.progress.setRange(0, 100)
2762 self.progress.hide()
2764 self.done_label = QLabel("All records fetched")
2765 self.done_label.hide()
2767 self.spacer = QLabel("")
2769 self.close_button = QToolButton()
2770 self.close_button.setIcon(parent.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
2771 self.close_button.released.connect(self.Deactivate)
2773 self.hbox = QHBoxLayout()
2774 self.hbox.setContentsMargins(0, 0, 0, 0)
2776 self.hbox.addWidget(self.label)
2777 self.hbox.addWidget(self.fetch_count)
2778 self.hbox.addWidget(self.fetch)
2779 self.hbox.addWidget(self.spacer)
2780 self.hbox.addWidget(self.progress)
2781 self.hbox.addWidget(self.done_label)
2782 self.hbox.addWidget(self.close_button)
2784 self.bar = QWidget()
2785 self.bar.setLayout(self.hbox)
2786 self.bar.show()
2788 self.in_progress = False
2789 self.model.progress.connect(self.Progress)
2791 self.done = False
2794 self.Done()
2796 def Widget(self):
2797 return self.bar
2799 def Activate(self):
2800 self.bar.show()
2801 self.fetch.setFocus()
2803 def Deactivate(self):
2804 self.bar.hide()
2806 def Enable(self, enable):
2807 self.fetch.setEnabled(enable)
2808 self.fetch_count.setEnabled(enable)
2810 def Busy(self):
2811 self.Enable(False)
2812 self.fetch.hide()
2813 self.spacer.hide()
2814 self.progress.show()
2816 def Idle(self):
2817 self.in_progress = False
2818 self.Enable(True)
2819 self.progress.hide()
2820 self.fetch.show()
2821 self.spacer.show()
2823 def Target(self):
2824 return self.fetch_count.value() * glb_chunk_sz
2826 def Done(self):
2827 self.done = True
2828 self.Idle()
2829 self.label.hide()
2830 self.fetch_count.hide()
2831 self.fetch.hide()
2832 self.spacer.hide()
2833 self.done_label.show()
2835 def Progress(self, count):
2836 if self.in_progress:
2838 percent = ((count - self.start) * 100) / self.Target()
2840 self.Idle()
2842 self.progress.setValue(percent)
2845 self.Done()
2847 def FetchMoreRecords(self):
2848 if self.done:
2850 self.progress.setValue(0)
2851 self.Busy()
2852 self.in_progress = True
2853 self.start = self.model.FetchMoreRecords(self.Target())
2859 def __init__(self, row, col, text, parent_item):
2860 self.row = row
2861 self.parent_item = parent_item
2862 self.data = [""] * (col + 1)
2863 self.data[col] = text
2864 self.level = 2
2866 def getParentItem(self):
2867 return self.parent_item
2869 def getRow(self):
2870 return self.row
2872 def childCount(self):
2875 def hasChildren(self):
2878 def getData(self, column):
2879 return self.data[column]
2885 def __init__(self, glb, row, data, parent_item):
2886 self.glb = glb
2887 self.row = row
2888 self.parent_item = parent_item
2889 self.child_count = 0
2890 self.child_items = []
2891 self.data = data[1:]
2892 self.dbid = data[0]
2893 self.level = 1
2894 self.query_done = False
2895 self.br_col = len(self.data) - 1
2897 def getChildItem(self, row):
2898 return self.child_items[row]
2900 def getParentItem(self):
2901 return self.parent_item
2903 def getRow(self):
2904 return self.row
2906 def Select(self):
2907 self.query_done = True
2909 if not self.glb.have_disassembler:
2912 query = QSqlQuery(self.glb.db)
2918 " WHERE samples.id = " + str(self.dbid))
2936 " WHERE samples.id > " + str(self.dbid) + " AND cpu = " + str(cpu) +
2953 inst = self.glb.disassembler.Instruction()
2954 f = self.glb.FileFromNamesAndBuildId(short_name, long_name, build_id)
2958 self.glb.disassembler.SetMode(inst, mode)
2967 cnt, text = self.glb.disassembler.DisassembleOne(inst, buf_ptr, buf_sz, ip)
2976 self.child_items.append(BranchLevelTwoItem(0, self.br_col, byte_str + " " + text, self))
2977 self.child_count += 1
2985 def childCount(self):
2986 if not self.query_done:
2987 self.Select()
2988 if not self.child_count:
2990 return self.child_count
2992 def hasChildren(self):
2993 if not self.query_done:
2995 return self.child_count > 0
2997 def getData(self, column):
2998 return self.data[column]
3004 def __init__(self):
3005 self.child_count = 0
3006 self.child_items = []
3007 self.level = 0
3009 def getChildItem(self, row):
3010 return self.child_items[row]
3012 def getParentItem(self):
3015 def getRow(self):
3018 def childCount(self):
3019 return self.child_count
3021 def hasChildren(self):
3022 return self.child_count > 0
3024 def getData(self, column):
3095 def __init__(self, glb, event_id, where_clause, parent=None):
3096 super(BranchModel, self).__init__(glb, None, parent)
3097 self.event_id = event_id
3098 self.more = True
3099 self.populated = 0
3100 self.have_ipc = IsSelectable(glb.db, "samples", columns = "insn_count, cyc_count")
3101 if self.have_ipc:
3123 " AND evsel_id = " + str(self.event_id) +
3130 self.fetcher = SQLFetcher(glb, sql, prep, self.AddSample)
3131 self.fetcher.done.connect(self.Update)
3132 self.fetcher.Fetch(glb_chunk_sz)
3134 def GetRoot(self):
3137 def columnCount(self, parent=None):
3138 if self.have_ipc:
3143 def columnHeader(self, column):
3144 if self.have_ipc:
3149 def columnFont(self, column):
3150 if self.have_ipc:
3158 def DisplayData(self, item, index):
3160 self.FetchIfNeeded(item.row)
3163 def AddSample(self, data):
3164 child = BranchLevelOneItem(self.glb, self.populated, data, self.root)
3165 self.root.child_items.append(child)
3166 self.populated += 1
3168 def Update(self, fetched):
3170 self.more = False
3171 self.progress.emit(0)
3172 child_count = self.root.child_count
3173 count = self.populated - child_count
3176 self.beginInsertRows(parent, child_count, child_count + count - 1)
3177 self.insertRows(child_count, count, parent)
3178 self.root.child_count += count
3179 self.endInsertRows()
3180 self.progress.emit(self.root.child_count)
3182 def FetchMoreRecords(self, count):
3183 current = self.root.child_count
3184 if self.more:
3185 self.fetcher.Fetch(count)
3187 self.progress.emit(0)
3190 def HasMoreRecords(self):
3191 return self.more
3197 def __init__(self, name = "", where_clause = "", limit = ""):
3198 self.name = name
3199 self.where_clause = where_clause
3200 self.limit = limit
3202 def UniqueId(self):
3203 return str(self.where_clause + ";" + self.limit)
3209 def __init__(self, glb, event_id, report_vars, parent=None):
3210 super(BranchWindow, self).__init__(parent)
3214 self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, report_vars.where_clause))
3216 self.view = QTreeView()
3217 self.view.setUniformRowHeights(True)
3218 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
3219 self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
3220 self.view.setModel(self.model)
3222 self.ResizeColumnsToContents()
3224 self.context_menu = TreeContextMenu(self.view)
3226 self.find_bar = FindBar(self, self, True)
3228 self.finder = ChildDataItemFinder(self.model.root)
3230 self.fetch_bar = FetchMoreRecordsBar(self.model, self)
3232 self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())
3234 self.setWidget(self.vbox.Widget())
3236 AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name + " Branch Events")
3238 def ResizeColumnToContents(self, column, n):
3242 font = self.view.font()
3246 val = self.model.root.child_items[row].data[column]
3249 val = self.model.columnHeader(column)
3252 self.view.setColumnWidth(column, max)
3254 def ResizeColumnsToContents(self):
3255 n = min(self.model.root.child_count, 100)
3258 self.model.rowsInserted.connect(self.UpdateColumnWidths)
3260 columns = self.model.columnCount()
3262 self.ResizeColumnToContents(i, n)
3264 def UpdateColumnWidths(self, *x):
3266 self.model.rowsInserted.disconnect(self.UpdateColumnWidths)
3267 self.ResizeColumnsToContents()
3269 def Find(self, value, direction, pattern, context):
3270 self.view.setFocus()
3271 self.find_bar.Busy()
3272 self.finder.Find(value, direction, pattern, context, self.FindDone)
3274 def FindDone(self, row):
3275 self.find_bar.Idle()
3277 self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))
3279 self.find_bar.NotFound()
3285 def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
3286 self.glb = glb
3287 self.label = label
3288 self.placeholder_text = placeholder_text
3289 self.parent = parent
3290 self.id = id
3292 self.value = default
3294 self.widget = QLineEdit(default)
3295 self.widget.editingFinished.connect(self.Validate)
3296 self.widget.textChanged.connect(self.Invalidate)
3297 self.red = False
3298 self.error = ""
3299 self.validated = True
3302 self.widget.setPlaceholderText(placeholder_text)
3304 def TurnTextRed(self):
3305 if not self.red:
3308 self.widget.setPalette(palette)
3309 self.red = True
3311 def TurnTextNormal(self):
3312 if self.red:
3314 self.widget.setPalette(palette)
3315 self.red = False
3317 def InvalidValue(self, value):
3318 self.value = ""
3319 self.TurnTextRed()
3320 self.error = self.label + " invalid value '" + value + "'"
3321 self.parent.ShowMessage(self.error)
3323 def Invalidate(self):
3324 self.validated = False
3326 def DoValidate(self, input_string):
3327 self.value = input_string.strip()
3329 def Validate(self):
3330 self.validated = True
3331 self.error = ""
3332 self.TurnTextNormal()
3333 self.parent.ClearMessage()
3334 input_string = self.widget.text()
3336 self.value = ""
3338 self.DoValidate(input_string)
3340 def IsValid(self):
3341 if not self.validated:
3342 self.Validate()
3343 if len(self.error):
3344 self.parent.ShowMessage(self.error)
3348 def IsNumber(self, value):
3359 def __init__(self, glb, label, placeholder_text, column_name, parent):
3360 super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent)
3362 self.column_name = column_name
3364 def DoValidate(self, input_string):
3370 if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
3371 return self.InvalidValue(value)
3374 if not self.IsNumber(value):
3375 return self.InvalidValue(value)
3377 ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
3379 ranges.append(self.column_name + " IN (" + ",".join(singles) + ")")
3380 self.value = " OR ".join(ranges)
3386 def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
3387 super(PositiveIntegerDataItem, self).__init__(glb, label, placeholder_text, parent, id, default)
3389 def DoValidate(self, input_string):
3390 if not self.IsNumber(input_string.strip()):
3391 return self.InvalidValue(input_string)
3394 return self.InvalidValue(input_string)
3395 self.value = str(value)
3401 def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent):
3402 super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent)
3404 self.table_name = table_name
3405 self.match_column = match_column
3406 self.column_name1 = column_name1
3407 self.column_name2 = column_name2
3409 def ValueToIds(self, value):
3411 query = QSqlQuery(self.glb.db)
3412 stmt = "SELECT id FROM " + self.table_name + " WHERE " + self.match_column + " = '" + value + "'"
3419 def DoValidate(self, input_string):
3422 ids = self.ValueToIds(value)
3426 return self.InvalidValue(value)
3427 self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
3428 if self.column_name2:
3429 self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"
3435 def __init__(self, glb, label, placeholder_text, column_name, parent):
3436 self.column_name = column_name
3438 self.last_id = 0
3439 self.first_time = 0
3440 self.last_time = 2 ** 64
3445 self.last_id = int(query.value(0))
3446 self.first_time = int(glb.HostStartTime())
3447 self.last_time = int(glb.HostFinishTime())
3449 placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)
3451 super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent)
3453 def IdBetween(self, query, lower_id, higher_id, order):
3460 def BinarySearchTime(self, lower_id, higher_id, target_time, get_floor):
3461 query = QSqlQuery(self.glb.db)
3466 ok, dbid = self.IdBetween(query, lower_id, next_id, "DESC")
3468 ok, dbid = self.IdBetween(query, next_id, higher_id, "")
3489 def ConvertRelativeTime(self, val):
3501 if not self.IsNumber(val):
3505 val += self.first_time
3507 val += self.last_time
3510 def ConvertTimeRange(self, vrange):
3512 vrange[0] = str(self.first_time)
3514 vrange[1] = str(self.last_time)
3515 vrange[0] = self.ConvertRelativeTime(vrange[0])
3516 vrange[1] = self.ConvertRelativeTime(vrange[1])
3517 if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
3519 beg_range = max(int(vrange[0]), self.first_time)
3520 end_range = min(int(vrange[1]), self.last_time)
3521 if beg_range > self.last_time or end_range < self.first_time:
3523 vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)
3524 vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False)
3527 def AddTimeRange(self, value, ranges):
3540 if self.ConvertTimeRange(vrange):
3545 def DoValidate(self, input_string):
3548 if not self.AddTimeRange(value, ranges):
3549 return self.InvalidValue(value)
3550 ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
3551 self.value = " OR ".join(ranges)
3557 def __init__(self, glb, title, items, partial, parent=None):
3558 super(ReportDialogBase, self).__init__(parent)
3560 self.glb = glb
3562 self.report_vars = ReportVars()
3564 self.setWindowTitle(title)
3565 self.setMinimumWidth(600)
3567 self.data_items = [x(glb, self) for x in items]
3569 self.partial = partial
3571 self.grid = QGridLayout()
3573 for row in xrange(len(self.data_items)):
3574 self.grid.addWidget(QLabel(self.data_items[row].label), row, 0)
3575 self.grid.addWidget(self.data_items[row].widget, row, 1)
3577 self.status = QLabel()
3579 self.ok_button = QPushButton("Ok", self)
3580 self.ok_button.setDefault(True)
3581 self.ok_button.released.connect(self.Ok)
3582 self.ok_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
3584 self.cancel_button = QPushButton("Cancel", self)
3585 self.cancel_button.released.connect(self.reject)
3586 self.cancel_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
3588 self.hbox = QHBoxLayout()
3589 #self.hbox.addStretch()
3590 self.hbox.addWidget(self.status)
3591 self.hbox.addWidget(self.ok_button)
3592 self.hbox.addWidget(self.cancel_button)
3594 self.vbox = QVBoxLayout()
3595 self.vbox.addLayout(self.grid)
3596 self.vbox.addLayout(self.hbox)
3598 self.setLayout(self.vbox)
3600 def Ok(self):
3601 vars = self.report_vars
3602 for d in self.data_items:
3606 self.ShowMessage("Report name is required")
3608 for d in self.data_items:
3611 for d in self.data_items[1:]:
3619 if self.partial:
3623 self.accept()
3625 def ShowMessage(self, msg):
3626 self.status.setText("<font color=#FF0000>" + msg)
3628 def ClearMessage(self):
3629 self.status.setText("")
3635 def __init__(self, glb, parent=None):
3646 super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent)
3672 def __init__(self, row, data):
3673 self.row = row
3674 self.data = data
3676 def getData(self, column):
3677 return self.data[column]
3685 def __init__(self, glb, sql, column_headers, parent=None):
3686 super(SQLTableModel, self).__init__(parent)
3687 self.glb = glb
3688 self.more = True
3689 self.populated = 0
3690 self.column_headers = column_headers
3691 self.fetcher = SQLFetcher(glb, sql, lambda x, y=len(column_headers): self.SQLTableDataPrep(x, y), self.AddSample)
3692 self.fetcher.done.connect(self.Update)
3693 self.fetcher.Fetch(glb_chunk_sz)
3695 def DisplayData(self, item, index):
3696 self.FetchIfNeeded(item.row)
3699 def AddSample(self, data):
3700 child = SQLTableItem(self.populated, data)
3701 self.child_items.append(child)
3702 self.populated += 1
3704 def Update(self, fetched):
3706 self.more = False
3707 self.progress.emit(0)
3708 child_count = self.child_count
3709 count = self.populated - child_count
3712 self.beginInsertRows(parent, child_count, child_count + count - 1)
3713 self.insertRows(child_count, count, parent)
3714 self.child_count += count
3715 self.endInsertRows()
3716 self.progress.emit(self.child_count)
3718 def FetchMoreRecords(self, count):
3719 current = self.child_count
3720 if self.more:
3721 self.fetcher.Fetch(count)
3723 self.progress.emit(0)
3726 def HasMoreRecords(self):
3727 return self.more
3729 def columnCount(self, parent=None):
3730 return len(self.column_headers)
3732 def columnHeader(self, column):
3733 return self.column_headers[column]
3735 def SQLTableDataPrep(self, query, count):
3745 def __init__(self, glb, table_name, parent=None):
3771 self.SQLTableDataPrep = self.samples_view_DataPrep
3773 self.SQLTableDataPrep = self.samples_DataPrep
3774 super(SQLAutoTableModel, self).__init__(glb, sql, column_headers, parent)
3776 def samples_view_DataPrep(self, query, count):
3785 def samples_DataPrep(self, query, count):
3799 def __init__(self, parent=None):
3800 super(ResizeColumnsToContentsBase, self).__init__(parent)
3802 def ResizeColumnToContents(self, column, n):
3805 font = self.view.font()
3809 val = self.data_model.child_items[row].data[column]
3812 val = self.data_model.columnHeader(column)
3815 self.view.setColumnWidth(column, max)
3817 def ResizeColumnsToContents(self):
3818 n = min(self.data_model.child_count, 100)
3821 self.data_model.rowsInserted.connect(self.UpdateColumnWidths)
3823 columns = self.data_model.columnCount()
3825 self.ResizeColumnToContents(i, n)
3827 def UpdateColumnWidths(self, *x):
3829 self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)
3830 self.ResizeColumnsToContents()
4037 def __init__(self, view):
4038 self.view = view
4039 self.view.setContextMenuPolicy(Qt.CustomContextMenu)
4040 self.view.customContextMenuRequested.connect(self.ShowContextMenu)
4042 def ShowContextMenu(self, pos):
4043 menu = QMenu(self.view)
4044 self.AddActions(menu)
4045 menu.exec_(self.view.mapToGlobal(pos))
4047 def AddCopy(self, menu):
4048 menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view))
4049 menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view))
4051 def AddActions(self, menu):
4052 self.AddCopy(menu)
4056 def __init__(self, view):
4057 super(TreeContextMenu, self).__init__(view)
4059 def AddActions(self, menu):
4060 i = self.view.currentIndex()
4063 menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view))
4064 self.AddCopy(menu)
4070 def __init__(self, glb, table_name, parent=None):
4071 super(TableWindow, self).__init__(parent)
4073 self.data_model = LookupCreateModel(table_name + " Table", lambda: SQLAutoTableModel(glb, table_name))
4075 self.model = QSortFilterProxyModel()
4076 self.model.setSourceModel(self.data_model)
4078 self.view = QTableView()
4079 self.view.setModel(self.model)
4080 self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
4081 self.view.verticalHeader().setVisible(False)
4082 self.view.sortByColumn(-1, Qt.AscendingOrder)
4083 self.view.setSortingEnabled(True)
4084 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
4085 self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
4087 self.ResizeColumnsToContents()
4089 self.context_menu = ContextMenu(self.view)
4091 self.find_bar = FindBar(self, self, True)
4093 self.finder = ChildDataItemFinder(self.data_model)
4095 self.fetch_bar = FetchMoreRecordsBar(self.data_model, self)
4097 self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())
4099 self.setWidget(self.vbox.Widget())
4101 AddSubWindow(glb.mainwindow.mdi_area, self, table_name + " Table")
4103 def Find(self, value, direction, pattern, context):
4104 self.view.setFocus()
4105 self.find_bar.Busy()
4106 self.finder.Find(value, direction, pattern, context, self.FindDone)
4108 def FindDone(self, row):
4109 self.find_bar.Idle()
4111 self.view.setCurrentIndex(self.model.mapFromSource(self.data_model.index(row, 0, QModelIndex())))
4113 self.find_bar.NotFound()
4138 def __init__(self, glb, report_vars, parent=None):
4168 self.alignment = (Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignLeft)
4169 super(TopCallsModel, self).__init__(glb, sql, column_headers, parent)
4171 def columnAlignment(self, column):
4172 return self.alignment[column]
4178 def __init__(self, glb, parent=None):
4188 super(TopCallsDialog, self).__init__(glb, title, items, False, parent)
4194 def __init__(self, glb, report_vars, parent=None):
4195 super(TopCallsWindow, self).__init__(parent)
4197 self.data_model = LookupCreateModel("Top Calls " + report_vars.UniqueId(), lambda: TopCallsModel(glb, report_vars))
4198 self.model = self.data_model
4200 self.view = QTableView()
4201 self.view.setModel(self.model)
4202 self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
4203 self.view.verticalHeader().setVisible(False)
4204 self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
4205 self.view.CopyCellsToClipboard = CopyTableCellsToClipboard
4207 self.context_menu = ContextMenu(self.view)
4209 self.ResizeColumnsToContents()
4211 self.find_bar = FindBar(self, self, True)
4213 self.finder = ChildDataItemFinder(self.model)
4215 self.fetch_bar = FetchMoreRecordsBar(self.data_model, self)
4217 self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())
4219 self.setWidget(self.vbox.Widget())
4221 AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name)
4223 def Find(self, value, direction, pattern, context):
4224 self.view.setFocus()
4225 self.find_bar.Busy()
4226 self.finder.Find(value, direction, pattern, context, self.FindDone)
4228 def FindDone(self, row):
4229 self.find_bar.Idle()
4231 self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))
4233 self.find_bar.NotFound()
4274 def __init__(self, mdi_area, menu):
4275 self.mdi_area = mdi_area
4276 self.window_menu = menu.addMenu("&Windows")
4277 self.close_active_window = CreateCloseActiveWindowAction(mdi_area)
4278 self.close_all_windows = CreateCloseAllWindowsAction(mdi_area)
4279 self.tile_windows = CreateTileWindowsAction(mdi_area)
4280 self.cascade_windows = CreateCascadeWindowsAction(mdi_area)
4281 self.next_window = CreateNextWindowAction(mdi_area)
4282 self.previous_window = CreatePreviousWindowAction(mdi_area)
4283 self.window_menu.aboutToShow.connect(self.Update)
4285 def Update(self):
4286 self.window_menu.clear()
4287 sub_window_count = len(self.mdi_area.subWindowList())
4289 self.close_active_window.setEnabled(have_sub_windows)
4290 self.close_all_windows.setEnabled(have_sub_windows)
4291 self.tile_windows.setEnabled(have_sub_windows)
4292 self.cascade_windows.setEnabled(have_sub_windows)
4293 self.next_window.setEnabled(have_sub_windows)
4294 self.previous_window.setEnabled(have_sub_windows)
4295 self.window_menu.addAction(self.close_active_window)
4296 self.window_menu.addAction(self.close_all_windows)
4297 self.window_menu.addSeparator()
4298 self.window_menu.addAction(self.tile_windows)
4299 self.window_menu.addAction(self.cascade_windows)
4300 self.window_menu.addSeparator()
4301 self.window_menu.addAction(self.next_window)
4302 self.window_menu.addAction(self.previous_window)
4305 self.window_menu.addSeparator()
4307 for sub_window in self.mdi_area.subWindowList():
4311 action = self.window_menu.addAction(label)
4313 action.setChecked(sub_window == self.mdi_area.activeSubWindow())
4314 action.triggered.connect(lambda a=None,x=nr: self.setActiveSubWindow(x))
4315 self.window_menu.addAction(action)
4318 def setActiveSubWindow(self, nr):
4319 self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1])
4472 def __init__(self, glb, parent=None):
4473 super(HelpWindow, self).__init__(parent)
4475 self.text = QTextBrowser()
4476 self.text.setHtml(glb_help_text)
4477 self.text.setReadOnly(True)
4478 self.text.setOpenExternalLinks(True)
4480 self.setWidget(self.text)
4482 AddSubWindow(glb.mainwindow.mdi_area, self, "Exported SQL Viewer Help")
4488 def __init__(self, parent=None):
4489 super(HelpOnlyWindow, self).__init__(parent)
4491 self.setMinimumSize(200, 100)
4492 self.resize(800, 600)
4493 self.setWindowTitle("Exported SQL Viewer Help")
4494 self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
4496 self.text = QTextBrowser()
4497 self.text.setHtml(glb_help_text)
4498 self.text.setReadOnly(True)
4499 self.text.setOpenExternalLinks(True)
4501 self.setCentralWidget(self.text)
4529 def __init__(self, glb, parent=None):
4530 super(AboutDialog, self).__init__(parent)
4532 self.setWindowTitle("About Exported SQL Viewer")
4533 self.setMinimumWidth(300)
4547 self.text = QTextBrowser()
4548 self.text.setHtml(text)
4549 self.text.setReadOnly(True)
4550 self.text.setOpenExternalLinks(True)
4552 self.vbox = QVBoxLayout()
4553 self.vbox.addWidget(self.text)
4555 self.setLayout(self.vbox)
4608 def __init__(self, glb, parent=None):
4609 super(MainWindow, self).__init__(parent)
4611 self.glb = glb
4613 self.setWindowTitle("Exported SQL Viewer: " + glb.dbname)
4614 self.setWindowIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
4615 self.setMinimumSize(200, 100)
4617 self.mdi_area = QMdiArea()
4618 self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
4619 self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
4621 self.setCentralWidget(self.mdi_area)
4623 menu = self.menuBar()
4626 file_menu.addAction(CreateExitAction(glb.app, self))
4629 edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy))
4630 edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))
4631 edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))
4632 edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))
4633 edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")]))
4634 edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")]))
4638 reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self))
4641 reports_menu.addAction(CreateAction("Call &Tree", "Create a new window containing a call tree", self.NewCallTree, self))
4643 self.EventMenu(GetEventList(glb.db), reports_menu)
4646 reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self))
4650 charts_menu.addAction(CreateAction("&Time chart by CPU", "Create a new window displaying time charts by CPU", self.TimeChartByCPU, self))
4652 self.TableMenu(GetTableList(glb), menu)
4654 self.window_menu = WindowMenu(self.mdi_area, menu)
4657 help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
4658 help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self))
4660 def Try(self, fn):
4661 win = self.mdi_area.activeSubWindow()
4668 def CopyToClipboard(self):
4669 self.Try(CopyCellsToClipboardHdr)
4671 def CopyToClipboardCSV(self):
4672 self.Try(CopyCellsToClipboardCSV)
4674 def Find(self):
4675 win = self.mdi_area.activeSubWindow()
4682 def FetchMoreRecords(self):
4683 win = self.mdi_area.activeSubWindow()
4690 def ShrinkFont(self):
4691 self.Try(ShrinkFont)
4693 def EnlargeFont(self):
4694 self.Try(EnlargeFont)
4696 def EventMenu(self, events, reports_menu):
4708 reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewBranchView(x), self))
4710 reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewSelectedBranchView(x), self))
4712 def TimeChartByCPU(self):
4713 TimeChartByCPUWindow(self.glb, self)
4715 def TableMenu(self, tables, menu):
4718 table_menu.addAction(CreateAction(table, "Create a new window containing a table view", lambda a=None,t=table: self.NewTableView(t), self))
4720 def NewCallGraph(self):
4721 CallGraphWindow(self.glb, self)
4723 def NewCallTree(self):
4724 CallTreeWindow(self.glb, self)
4726 def NewTopCalls(self):
4727 dialog = TopCallsDialog(self.glb, self)
4730 TopCallsWindow(self.glb, dialog.report_vars, self)
4732 def NewBranchView(self, event_id):
4733 BranchWindow(self.glb, event_id, ReportVars(), self)
4735 def NewSelectedBranchView(self, event_id):
4736 dialog = SelectedBranchDialog(self.glb, self)
4739 BranchWindow(self.glb, event_id, dialog.report_vars, self)
4741 def NewTableView(self, table_name):
4742 TableWindow(self.glb, table_name, self)
4744 def Help(self):
4745 HelpWindow(self.glb, self)
4747 def About(self):
4748 dialog = AboutDialog(self.glb, self)
4781 def __init__(self, dbref, db, dbname):
4782 self.dbref = dbref
4783 self.db = db
4784 self.dbname = dbname
4785 self.home_dir = os.path.expanduser("~")
4786 self.buildid_dir = os.getenv("PERF_BUILDID_DIR")
4787 if self.buildid_dir:
4788 self.buildid_dir += "/.build-id/"
4790 self.buildid_dir = self.home_dir + "/.debug/.build-id/"
4791 self.app = None
4792 self.mainwindow = None
4793 self.instances_to_shutdown_on_exit = weakref.WeakSet()
4795 self.disassembler = LibXED()
4796 self.have_disassembler = True
4798 self.have_disassembler = False
4799 self.host_machine_id = 0
4800 self.host_start_time = 0
4801 self.host_finish_time = 0
4803 def FileFromBuildId(self, build_id):
4804 file_name = self.buildid_dir + build_id[0:2] + "/" + build_id[2:] + "/elf"
4807 def FileFromNamesAndBuildId(self, short_name, long_name, build_id):
4818 f = self.FileFromBuildId(build_id)
4823 def AddInstanceToShutdownOnExit(self, instance):
4824 self.instances_to_shutdown_on_exit.add(instance)
4827 def ShutdownInstances(self):
4828 for x in self.instances_to_shutdown_on_exit:
4834 def GetHostMachineId(self):
4835 query = QSqlQuery(self.db)
4838 self.host_machine_id = query.value(0)
4840 self.host_machine_id = 0
4841 return self.host_machine_id
4843 def HostMachineId(self):
4844 if self.host_machine_id:
4845 return self.host_machine_id
4846 return self.GetHostMachineId()
4848 def SelectValue(self, sql):
4849 query = QSqlQuery(self.db)
4858 def SwitchesMinTime(self, machine_id):
4859 return self.SelectValue("SELECT time"
4864 def SwitchesMaxTime(self, machine_id):
4865 return self.SelectValue("SELECT time"
4870 def SamplesMinTime(self, machine_id):
4871 return self.SelectValue("SELECT time"
4876 def SamplesMaxTime(self, machine_id):
4877 return self.SelectValue("SELECT time"
4882 def CallsMinTime(self, machine_id):
4883 return self.SelectValue("SELECT calls.call_time"
4889 def CallsMaxTime(self, machine_id):
4890 return self.SelectValue("SELECT calls.return_time"
4896 def GetStartTime(self, machine_id):
4897 t0 = self.SwitchesMinTime(machine_id)
4898 t1 = self.SamplesMinTime(machine_id)
4899 t2 = self.CallsMinTime(machine_id)
4906 def GetFinishTime(self, machine_id):
4907 t0 = self.SwitchesMaxTime(machine_id)
4908 t1 = self.SamplesMaxTime(machine_id)
4909 t2 = self.CallsMaxTime(machine_id)
4916 def HostStartTime(self):
4917 if self.host_start_time:
4918 return self.host_start_time
4919 self.host_start_time = self.GetStartTime(self.HostMachineId())
4920 return self.host_start_time
4922 def HostFinishTime(self):
4923 if self.host_finish_time:
4924 return self.host_finish_time
4925 self.host_finish_time = self.GetFinishTime(self.HostMachineId())
4926 return self.host_finish_time
4928 def StartTime(self, machine_id):
4929 if machine_id == self.HostMachineId():
4930 return self.HostStartTime()
4931 return self.GetStartTime(machine_id)
4933 def FinishTime(self, machine_id):
4934 if machine_id == self.HostMachineId():
4935 return self.HostFinishTime()
4936 return self.GetFinishTime(machine_id)
4942 def __init__(self, is_sqlite3, dbname):
4943 self.is_sqlite3 = is_sqlite3
4944 self.dbname = dbname
4945 self.TRUE = "TRUE"
4946 self.FALSE = "FALSE"
4948 if self.is_sqlite3:
4949 self.TRUE = "1"
4950 self.FALSE = "0"
4952 def Open(self, connection_name):
4953 dbname = self.dbname
4954 if self.is_sqlite3: