#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0
# exported-sql-viewer.py: view data from sql database
# Copyright (c) 2014-2018, Intel Corporation.

# To use this script you will need to have exported data using either the
# export-to-sqlite.py or the export-to-postgresql.py script.  Refer to those
# scripts for details.
#
# Following on from the example in the export scripts, a
# call-graph can be displayed for the pt_example database like this:
#
#	python tools/perf/scripts/python/exported-sql-viewer.py pt_example
#
# Note that for PostgreSQL, this script supports connecting to remote databases
# by setting hostname, port, username, password, and dbname e.g.
#
#	python tools/perf/scripts/python/exported-sql-viewer.py "hostname=myhost username=myuser password=mypassword dbname=pt_example"
#
# The result is a GUI window with a tree representing a context-sensitive
# call-graph.  Expanding a couple of levels of the tree and adjusting column
# widths to suit will display something like:
#
#                                         Call Graph: pt_example
# Call Path                          Object      Count   Time(ns)  Time(%)  Branch Count   Branch Count(%)
# v- ls
#     v- 2638:2638
#         v- _start                  ld-2.19.so    1     10074071   100.0         211135            100.0
#           |- unknown               unknown       1        13198     0.1              1              0.0
#           >- _dl_start             ld-2.19.so    1      1400980    13.9          19637              9.3
#           >- _d_linit_internal     ld-2.19.so    1       448152     4.4          11094              5.3
#           v-__libc_start_main@plt  ls            1      8211741    81.5         180397             85.4
#              >- _dl_fixup          ld-2.19.so    1         7607     0.1            108              0.1
#              >- __cxa_atexit       libc-2.19.so  1        11737     0.1             10              0.0
#              >- __libc_csu_init    ls            1        10354     0.1             10              0.0
#              |- _setjmp            libc-2.19.so  1            0     0.0              4              0.0
#              v- main               ls            1      8182043    99.6         180254             99.9
#
# Points to note:
#	The top level is a command name (comm)
#	The next level is a thread (pid:tid)
#	Subsequent levels are functions
#	'Count' is the number of calls
#	'Time' is the elapsed time until the function returns
#	Percentages are relative to the level above
#	'Branch Count' is the total number of branches for that function and all
#       functions that it calls

# There is also a "All branches" report, which displays branches and
# possibly disassembly.  However, presently, the only supported disassembler is
# Intel XED, and additionally the object code must be present in perf build ID
# cache. To use Intel XED, libxed.so must be present. To build and install
# libxed.so:
#            git clone https://github.com/intelxed/mbuild.git mbuild
#            git clone https://github.com/intelxed/xed
#            cd xed
#            ./mfile.py --share
#            sudo ./mfile.py --prefix=/usr/local install
#            sudo ldconfig
#
# Example report:
#
# Time           CPU  Command  PID    TID    Branch Type            In Tx  Branch
# 8107675239590  2    ls       22011  22011  return from interrupt  No     ffffffff86a00a67 native_irq_return_iret ([kernel]) -> 7fab593ea260 _start (ld-2.19.so)
#                                                                              7fab593ea260 48 89 e7                                        mov %rsp, %rdi
# 8107675239899  2    ls       22011  22011  hardware interrupt     No         7fab593ea260 _start (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])
# 8107675241900  2    ls       22011  22011  return from interrupt  No     ffffffff86a00a67 native_irq_return_iret ([kernel]) -> 7fab593ea260 _start (ld-2.19.so)
#                                                                              7fab593ea260 48 89 e7                                        mov %rsp, %rdi
#                                                                              7fab593ea263 e8 c8 06 00 00                                  callq  0x7fab593ea930
# 8107675241900  2    ls       22011  22011  call                   No         7fab593ea263 _start+0x3 (ld-2.19.so) -> 7fab593ea930 _dl_start (ld-2.19.so)
#                                                                              7fab593ea930 55                                              pushq  %rbp
#                                                                              7fab593ea931 48 89 e5                                        mov %rsp, %rbp
#                                                                              7fab593ea934 41 57                                           pushq  %r15
#                                                                              7fab593ea936 41 56                                           pushq  %r14
#                                                                              7fab593ea938 41 55                                           pushq  %r13
#                                                                              7fab593ea93a 41 54                                           pushq  %r12
#                                                                              7fab593ea93c 53                                              pushq  %rbx
#                                                                              7fab593ea93d 48 89 fb                                        mov %rdi, %rbx
#                                                                              7fab593ea940 48 83 ec 68                                     sub $0x68, %rsp
#                                                                              7fab593ea944 0f 31                                           rdtsc
#                                                                              7fab593ea946 48 c1 e2 20                                     shl $0x20, %rdx
#                                                                              7fab593ea94a 89 c0                                           mov %eax, %eax
#                                                                              7fab593ea94c 48 09 c2                                        or %rax, %rdx
#                                                                              7fab593ea94f 48 8b 05 1a 15 22 00                            movq  0x22151a(%rip), %rax
# 8107675242232  2    ls       22011  22011  hardware interrupt     No         7fab593ea94f _dl_start+0x1f (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])
# 8107675242900  2    ls       22011  22011  return from interrupt  No     ffffffff86a00a67 native_irq_return_iret ([kernel]) -> 7fab593ea94f _dl_start+0x1f (ld-2.19.so)
#                                                                              7fab593ea94f 48 8b 05 1a 15 22 00                            movq  0x22151a(%rip), %rax
#                                                                              7fab593ea956 48 89 15 3b 13 22 00                            movq  %rdx, 0x22133b(%rip)
# 8107675243232  2    ls       22011  22011  hardware interrupt     No         7fab593ea956 _dl_start+0x26 (ld-2.19.so) -> ffffffff86a012e0 page_fault ([kernel])

from __future__ import print_function

import sys
# Only change warnings if the python -W option was not used
if not sys.warnoptions:
	import warnings
	# PySide2 causes deprecation warnings, ignore them.
	warnings.filterwarnings("ignore", category=DeprecationWarning)
import argparse
import weakref
import threading
import string
try:
	# Python2
	import cPickle as pickle
	# size of pickled integer big enough for record size
	glb_nsz = 8
except ImportError:
	import pickle
	glb_nsz = 16
import re
import os
import random
import copy
import math
from libxed import LibXED

pyside_version_1 = True
if not "--pyside-version-1" in sys.argv:
	try:
		from PySide2.QtCore import *
		from PySide2.QtGui import *
		from PySide2.QtSql import *
		from PySide2.QtWidgets import *
		pyside_version_1 = False
	except:
		pass

if pyside_version_1:
	from PySide.QtCore import *
	from PySide.QtGui import *
	from PySide.QtSql import *

from decimal import Decimal, ROUND_HALF_UP
from ctypes import CDLL, Structure, create_string_buffer, addressof, sizeof, \
		   c_void_p, c_bool, c_byte, c_char, c_int, c_uint, c_longlong, c_ulonglong
from multiprocessing import Process, Array, Value, Event

# xrange is range in Python3
try:
	xrange
except NameError:
	xrange = range

def printerr(*args, **keyword_args):
	print(*args, file=sys.stderr, **keyword_args)

# Data formatting helpers

def tohex(ip):
	if ip < 0:
		ip += 1 << 64
	return "%x" % ip

def offstr(offset):
	if offset:
		return "+0x%x" % offset
	return ""

def dsoname(name):
	if name == "[kernel.kallsyms]":
		return "[kernel]"
	return name

def findnth(s, sub, n, offs=0):
	pos = s.find(sub)
	if pos < 0:
		return pos
	if n <= 1:
		return offs + pos
	return findnth(s[pos + 1:], sub, n - 1, offs + pos + 1)

# Percent to one decimal place

def PercentToOneDP(n, d):
	if not d:
		return "0.0"
	x = (n * Decimal(100)) / d
	return str(x.quantize(Decimal(".1"), rounding=ROUND_HALF_UP))

# Helper for queries that must not fail

def QueryExec(query, stmt):
	ret = query.exec_(stmt)
	if not ret:
		raise Exception("Query failed: " + query.lastError().text())

# Background thread

class Thread(QThread):

	done = Signal(object)

	def __init__(self, task, param=None, parent=None):
		super(Thread, self).__init__(parent)
		self.task = task
		self.param = param

	def run(self):
		while True:
			if self.param is None:
				done, result = self.task()
			else:
				done, result = self.task(self.param)
			self.done.emit(result)
			if done:
				break

# Tree data model

class TreeModel(QAbstractItemModel):

	def __init__(self, glb, params, parent=None):
		super(TreeModel, self).__init__(parent)
		self.glb = glb
		self.params = params
		self.root = self.GetRoot()
		self.last_row_read = 0

	def Item(self, parent):
		if parent.isValid():
			return parent.internalPointer()
		else:
			return self.root

	def rowCount(self, parent):
		result = self.Item(parent).childCount()
		if result < 0:
			result = 0
			self.dataChanged.emit(parent, parent)
		return result

	def hasChildren(self, parent):
		return self.Item(parent).hasChildren()

	def headerData(self, section, orientation, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(section)
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.columnHeader(section)

	def parent(self, child):
		child_item = child.internalPointer()
		if child_item is self.root:
			return QModelIndex()
		parent_item = child_item.getParentItem()
		return self.createIndex(parent_item.getRow(), 0, parent_item)

	def index(self, row, column, parent):
		child_item = self.Item(parent).getChildItem(row)
		return self.createIndex(row, column, child_item)

	def DisplayData(self, item, index):
		return item.getData(index.column())

	def FetchIfNeeded(self, row):
		if row > self.last_row_read:
			self.last_row_read = row
			if row + 10 >= self.root.child_count:
				self.fetcher.Fetch(glb_chunk_sz)

	def columnAlignment(self, column):
		return Qt.AlignLeft

	def columnFont(self, column):
		return None

	def data(self, index, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(index.column())
		if role == Qt.FontRole:
			return self.columnFont(index.column())
		if role != Qt.DisplayRole:
			return None
		item = index.internalPointer()
		return self.DisplayData(item, index)

# Table data model

class TableModel(QAbstractTableModel):

	def __init__(self, parent=None):
		super(TableModel, self).__init__(parent)
		self.child_count = 0
		self.child_items = []
		self.last_row_read = 0

	def Item(self, parent):
		if parent.isValid():
			return parent.internalPointer()
		else:
			return self

	def rowCount(self, parent):
		return self.child_count

	def headerData(self, section, orientation, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(section)
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.columnHeader(section)

	def index(self, row, column, parent):
		return self.createIndex(row, column, self.child_items[row])

	def DisplayData(self, item, index):
		return item.getData(index.column())

	def FetchIfNeeded(self, row):
		if row > self.last_row_read:
			self.last_row_read = row
			if row + 10 >= self.child_count:
				self.fetcher.Fetch(glb_chunk_sz)

	def columnAlignment(self, column):
		return Qt.AlignLeft

	def columnFont(self, column):
		return None

	def data(self, index, role):
		if role == Qt.TextAlignmentRole:
			return self.columnAlignment(index.column())
		if role == Qt.FontRole:
			return self.columnFont(index.column())
		if role != Qt.DisplayRole:
			return None
		item = index.internalPointer()
		return self.DisplayData(item, index)

# Model cache

model_cache = weakref.WeakValueDictionary()
model_cache_lock = threading.Lock()

def LookupCreateModel(model_name, create_fn):
	model_cache_lock.acquire()
	try:
		model = model_cache[model_name]
	except:
		model = None
	if model is None:
		model = create_fn()
		model_cache[model_name] = model
	model_cache_lock.release()
	return model

def LookupModel(model_name):
	model_cache_lock.acquire()
	try:
		model = model_cache[model_name]
	except:
		model = None
	model_cache_lock.release()
	return model

# Find bar

class FindBar():

	def __init__(self, parent, finder, is_reg_expr=False):
		self.finder = finder
		self.context = []
		self.last_value = None
		self.last_pattern = None

		label = QLabel("Find:")
		label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.textbox = QComboBox()
		self.textbox.setEditable(True)
		self.textbox.currentIndexChanged.connect(self.ValueChanged)

		self.progress = QProgressBar()
		self.progress.setRange(0, 0)
		self.progress.hide()

		if is_reg_expr:
			self.pattern = QCheckBox("Regular Expression")
		else:
			self.pattern = QCheckBox("Pattern")
		self.pattern.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.next_button = QToolButton()
		self.next_button.setIcon(parent.style().standardIcon(QStyle.SP_ArrowDown))
		self.next_button.released.connect(lambda: self.NextPrev(1))

		self.prev_button = QToolButton()
		self.prev_button.setIcon(parent.style().standardIcon(QStyle.SP_ArrowUp))
		self.prev_button.released.connect(lambda: self.NextPrev(-1))

		self.close_button = QToolButton()
		self.close_button.setIcon(parent.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
		self.close_button.released.connect(self.Deactivate)

		self.hbox = QHBoxLayout()
		self.hbox.setContentsMargins(0, 0, 0, 0)

		self.hbox.addWidget(label)
		self.hbox.addWidget(self.textbox)
		self.hbox.addWidget(self.progress)
		self.hbox.addWidget(self.pattern)
		self.hbox.addWidget(self.next_button)
		self.hbox.addWidget(self.prev_button)
		self.hbox.addWidget(self.close_button)

		self.bar = QWidget()
		self.bar.setLayout(self.hbox)
		self.bar.hide()

	def Widget(self):
		return self.bar

	def Activate(self):
		self.bar.show()
		self.textbox.lineEdit().selectAll()
		self.textbox.setFocus()

	def Deactivate(self):
		self.bar.hide()

	def Busy(self):
		self.textbox.setEnabled(False)
		self.pattern.hide()
		self.next_button.hide()
		self.prev_button.hide()
		self.progress.show()

	def Idle(self):
		self.textbox.setEnabled(True)
		self.progress.hide()
		self.pattern.show()
		self.next_button.show()
		self.prev_button.show()

	def Find(self, direction):
		value = self.textbox.currentText()
		pattern = self.pattern.isChecked()
		self.last_value = value
		self.last_pattern = pattern
		self.finder.Find(value, direction, pattern, self.context)

	def ValueChanged(self):
		value = self.textbox.currentText()
		pattern = self.pattern.isChecked()
		index = self.textbox.currentIndex()
		data = self.textbox.itemData(index)
		# Store the pattern in the combo box to keep it with the text value
		if data == None:
			self.textbox.setItemData(index, pattern)
		else:
			self.pattern.setChecked(data)
		self.Find(0)

	def NextPrev(self, direction):
		value = self.textbox.currentText()
		pattern = self.pattern.isChecked()
		if value != self.last_value:
			index = self.textbox.findText(value)
			# Allow for a button press before the value has been added to the combo box
			if index < 0:
				index = self.textbox.count()
				self.textbox.addItem(value, pattern)
				self.textbox.setCurrentIndex(index)
				return
			else:
				self.textbox.setItemData(index, pattern)
		elif pattern != self.last_pattern:
			# Keep the pattern recorded in the combo box up to date
			index = self.textbox.currentIndex()
			self.textbox.setItemData(index, pattern)
		self.Find(direction)

	def NotFound(self):
		QMessageBox.information(self.bar, "Find", "'" + self.textbox.currentText() + "' not found")

# Context-sensitive call graph data model item base

class CallGraphLevelItemBase(object):

	def __init__(self, glb, params, row, parent_item):
		self.glb = glb
		self.params = params
		self.row = row
		self.parent_item = parent_item
		self.query_done = False
		self.child_count = 0
		self.child_items = []
		if parent_item:
			self.level = parent_item.level + 1
		else:
			self.level = 0

	def getChildItem(self, row):
		return self.child_items[row]

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def childCount(self):
		if not self.query_done:
			self.Select()
			if not self.child_count:
				return -1
		return self.child_count

	def hasChildren(self):
		if not self.query_done:
			return True
		return self.child_count > 0

	def getData(self, column):
		return self.data[column]

# Context-sensitive call graph data model level 2+ item base

class CallGraphLevelTwoPlusItemBase(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, call_path_id, time, insn_cnt, cyc_cnt, branch_count, parent_item):
		super(CallGraphLevelTwoPlusItemBase, self).__init__(glb, params, row, parent_item)
		self.comm_id = comm_id
		self.thread_id = thread_id
		self.call_path_id = call_path_id
		self.insn_cnt = insn_cnt
		self.cyc_cnt = cyc_cnt
		self.branch_count = branch_count
		self.time = time

	def Select(self):
		self.query_done = True
		query = QSqlQuery(self.glb.db)
		if self.params.have_ipc:
			ipc_str = ", SUM(insn_count), SUM(cyc_count)"
		else:
			ipc_str = ""
		QueryExec(query, "SELECT call_path_id, name, short_name, COUNT(calls.id), SUM(return_time - call_time)" + ipc_str + ", SUM(branch_count)"
					" FROM calls"
					" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
					" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
					" INNER JOIN dsos ON symbols.dso_id = dsos.id"
					" WHERE parent_call_path_id = " + str(self.call_path_id) +
					" AND comm_id = " + str(self.comm_id) +
					" AND thread_id = " + str(self.thread_id) +
					" GROUP BY call_path_id, name, short_name"
					" ORDER BY call_path_id")
		while query.next():
			if self.params.have_ipc:
				insn_cnt = int(query.value(5))
				cyc_cnt = int(query.value(6))
				branch_count = int(query.value(7))
			else:
				insn_cnt = 0
				cyc_cnt = 0
				branch_count = int(query.value(5))
			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)
			self.child_items.append(child_item)
			self.child_count += 1

# Context-sensitive call graph data model level three item

class CallGraphLevelThreeItem(CallGraphLevelTwoPlusItemBase):

	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):
		super(CallGraphLevelThreeItem, self).__init__(glb, params, row, comm_id, thread_id, call_path_id, time, insn_cnt, cyc_cnt, branch_count, parent_item)
		dso = dsoname(dso)
		if self.params.have_ipc:
			insn_pcnt = PercentToOneDP(insn_cnt, parent_item.insn_cnt)
			cyc_pcnt = PercentToOneDP(cyc_cnt, parent_item.cyc_cnt)
			br_pcnt = PercentToOneDP(branch_count, parent_item.branch_count)
			ipc = CalcIPC(cyc_cnt, insn_cnt)
			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 ]
		else:
			self.data = [ name, dso, str(count), str(time), PercentToOneDP(time, parent_item.time), str(branch_count), PercentToOneDP(branch_count, parent_item.branch_count) ]
		self.dbid = call_path_id

# Context-sensitive call graph data model level two item

class CallGraphLevelTwoItem(CallGraphLevelTwoPlusItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, pid, tid, parent_item):
		super(CallGraphLevelTwoItem, self).__init__(glb, params, row, comm_id, thread_id, 1, 0, 0, 0, 0, parent_item)
		if self.params.have_ipc:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", ""]
		self.dbid = thread_id

	def Select(self):
		super(CallGraphLevelTwoItem, self).Select()
		for child_item in self.child_items:
			self.time += child_item.time
			self.insn_cnt += child_item.insn_cnt
			self.cyc_cnt += child_item.cyc_cnt
			self.branch_count += child_item.branch_count
		for child_item in self.child_items:
			child_item.data[4] = PercentToOneDP(child_item.time, self.time)
			if self.params.have_ipc:
				child_item.data[6] = PercentToOneDP(child_item.insn_cnt, self.insn_cnt)
				child_item.data[8] = PercentToOneDP(child_item.cyc_cnt, self.cyc_cnt)
				child_item.data[11] = PercentToOneDP(child_item.branch_count, self.branch_count)
			else:
				child_item.data[6] = PercentToOneDP(child_item.branch_count, self.branch_count)

# Context-sensitive call graph data model level one item

class CallGraphLevelOneItem(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, comm, parent_item):
		super(CallGraphLevelOneItem, self).__init__(glb, params, row, parent_item)
		if self.params.have_ipc:
			self.data = [comm, "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [comm, "", "", "", "", "", ""]
		self.dbid = comm_id

	def Select(self):
		self.query_done = True
		query = QSqlQuery(self.glb.db)
		QueryExec(query, "SELECT thread_id, pid, tid"
					" FROM comm_threads"
					" INNER JOIN threads ON thread_id = threads.id"
					" WHERE comm_id = " + str(self.dbid))
		while query.next():
			child_item = CallGraphLevelTwoItem(self.glb, self.params, self.child_count, self.dbid, query.value(0), query.value(1), query.value(2), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Context-sensitive call graph data model root item

class CallGraphRootItem(CallGraphLevelItemBase):

	def __init__(self, glb, params):
		super(CallGraphRootItem, self).__init__(glb, params, 0, None)
		self.dbid = 0
		self.query_done = True
		if_has_calls = ""
		if IsSelectable(glb.db, "comms", columns = "has_calls"):
			if_has_calls = " WHERE has_calls = " + glb.dbref.TRUE
		query = QSqlQuery(glb.db)
		QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls)
		while query.next():
			if not query.value(0):
				continue
			child_item = CallGraphLevelOneItem(glb, params, self.child_count, query.value(0), query.value(1), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call graph model parameters

class CallGraphModelParams():

	def __init__(self, glb, parent=None):
		self.have_ipc = IsSelectable(glb.db, "calls", columns = "insn_count, cyc_count")

# Context-sensitive call graph data model base

class CallGraphModelBase(TreeModel):

	def __init__(self, glb, parent=None):
		super(CallGraphModelBase, self).__init__(glb, CallGraphModelParams(glb), parent)

	def FindSelect(self, value, pattern, query):
		if pattern:
			# postgresql and sqlite pattern patching differences:
			#   postgresql LIKE is case sensitive but sqlite LIKE is not
			#   postgresql LIKE allows % and _ to be escaped with \ but sqlite LIKE does not
			#   postgresql supports ILIKE which is case insensitive
			#   sqlite supports GLOB (text only) which uses * and ? and is case sensitive
			if not self.glb.dbref.is_sqlite3:
				# Escape % and _
				s = value.replace("%", "\\%")
				s = s.replace("_", "\\_")
				# Translate * and ? into SQL LIKE pattern characters % and _
				trans = string.maketrans("*?", "%_")
				match = " LIKE '" + str(s).translate(trans) + "'"
			else:
				match = " GLOB '" + str(value) + "'"
		else:
			match = " = '" + str(value) + "'"
		self.DoFindSelect(query, match)

	def Found(self, query, found):
		if found:
			return self.FindPath(query)
		return []

	def FindValue(self, value, pattern, query, last_value, last_pattern):
		if last_value == value and pattern == last_pattern:
			found = query.first()
		else:
			self.FindSelect(value, pattern, query)
			found = query.next()
		return self.Found(query, found)

	def FindNext(self, query):
		found = query.next()
		if not found:
			found = query.first()
		return self.Found(query, found)

	def FindPrev(self, query):
		found = query.previous()
		if not found:
			found = query.last()
		return self.Found(query, found)

	def FindThread(self, c):
		if c.direction == 0 or c.value != c.last_value or c.pattern != c.last_pattern:
			ids = self.FindValue(c.value, c.pattern, c.query, c.last_value, c.last_pattern)
		elif c.direction > 0:
			ids = self.FindNext(c.query)
		else:
			ids = self.FindPrev(c.query)
		return (True, ids)

	def Find(self, value, direction, pattern, context, callback):
		class Context():
			def __init__(self, *x):
				self.value, self.direction, self.pattern, self.query, self.last_value, self.last_pattern = x
			def Update(self, *x):
				self.value, self.direction, self.pattern, self.last_value, self.last_pattern = x + (self.value, self.pattern)
		if len(context):
			context[0].Update(value, direction, pattern)
		else:
			context.append(Context(value, direction, pattern, QSqlQuery(self.glb.db), None, None))
		# Use a thread so the UI is not blocked during the SELECT
		thread = Thread(self.FindThread, context[0])
		thread.done.connect(lambda ids, t=thread, c=callback: self.FindDone(t, c, ids), Qt.QueuedConnection)
		thread.start()

	def FindDone(self, thread, callback, ids):
		callback(ids)

# Context-sensitive call graph data model

class CallGraphModel(CallGraphModelBase):

	def __init__(self, glb, parent=None):
		super(CallGraphModel, self).__init__(glb, parent)

	def GetRoot(self):
		return CallGraphRootItem(self.glb, self.params)

	def columnCount(self, parent=None):
		if self.params.have_ipc:
			return 12
		else:
			return 7

	def columnHeader(self, column):
		if self.params.have_ipc:
			headers = ["Call Path", "Object", "Count ", "Time (ns) ", "Time (%) ", "Insn Cnt", "Insn Cnt (%)", "Cyc Cnt", "Cyc Cnt (%)", "IPC", "Branch Count ", "Branch Count (%) "]
		else:
			headers = ["Call Path", "Object", "Count ", "Time (ns) ", "Time (%) ", "Branch Count ", "Branch Count (%) "]
		return headers[column]

	def columnAlignment(self, column):
		if self.params.have_ipc:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		else:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		return alignment[column]

	def DoFindSelect(self, query, match):
		QueryExec(query, "SELECT call_path_id, comm_id, thread_id"
						" FROM calls"
						" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
						" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
						" WHERE calls.id <> 0"
						" AND symbols.name" + match +
						" GROUP BY comm_id, thread_id, call_path_id"
						" ORDER BY comm_id, thread_id, call_path_id")

	def FindPath(self, query):
		# Turn the query result into a list of ids that the tree view can walk
		# to open the tree at the right place.
		ids = []
		parent_id = query.value(0)
		while parent_id:
			ids.insert(0, parent_id)
			q2 = QSqlQuery(self.glb.db)
			QueryExec(q2, "SELECT parent_id"
					" FROM call_paths"
					" WHERE id = " + str(parent_id))
			if not q2.next():
				break
			parent_id = q2.value(0)
		# The call path root is not used
		if ids[0] == 1:
			del ids[0]
		ids.insert(0, query.value(2))
		ids.insert(0, query.value(1))
		return ids

# Call tree data model level 2+ item base

class CallTreeLevelTwoPlusItemBase(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, calls_id, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item):
		super(CallTreeLevelTwoPlusItemBase, self).__init__(glb, params, row, parent_item)
		self.comm_id = comm_id
		self.thread_id = thread_id
		self.calls_id = calls_id
		self.call_time = call_time
		self.time = time
		self.insn_cnt = insn_cnt
		self.cyc_cnt = cyc_cnt
		self.branch_count = branch_count

	def Select(self):
		self.query_done = True
		if self.calls_id == 0:
			comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id)
		else:
			comm_thread = ""
		if self.params.have_ipc:
			ipc_str = ", insn_count, cyc_count"
		else:
			ipc_str = ""
		query = QSqlQuery(self.glb.db)
		QueryExec(query, "SELECT calls.id, name, short_name, call_time, return_time - call_time" + ipc_str + ", branch_count"
					" FROM calls"
					" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
					" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
					" INNER JOIN dsos ON symbols.dso_id = dsos.id"
					" WHERE calls.parent_id = " + str(self.calls_id) + comm_thread +
					" ORDER BY call_time, calls.id")
		while query.next():
			if self.params.have_ipc:
				insn_cnt = int(query.value(5))
				cyc_cnt = int(query.value(6))
				branch_count = int(query.value(7))
			else:
				insn_cnt = 0
				cyc_cnt = 0
				branch_count = int(query.value(5))
			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)
			self.child_items.append(child_item)
			self.child_count += 1

# Call tree data model level three item

class CallTreeLevelThreeItem(CallTreeLevelTwoPlusItemBase):

	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):
		super(CallTreeLevelThreeItem, self).__init__(glb, params, row, comm_id, thread_id, calls_id, call_time, time, insn_cnt, cyc_cnt, branch_count, parent_item)
		dso = dsoname(dso)
		if self.params.have_ipc:
			insn_pcnt = PercentToOneDP(insn_cnt, parent_item.insn_cnt)
			cyc_pcnt = PercentToOneDP(cyc_cnt, parent_item.cyc_cnt)
			br_pcnt = PercentToOneDP(branch_count, parent_item.branch_count)
			ipc = CalcIPC(cyc_cnt, insn_cnt)
			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 ]
		else:
			self.data = [ name, dso, str(call_time), str(time), PercentToOneDP(time, parent_item.time), str(branch_count), PercentToOneDP(branch_count, parent_item.branch_count) ]
		self.dbid = calls_id

# Call tree data model level two item

class CallTreeLevelTwoItem(CallTreeLevelTwoPlusItemBase):

	def __init__(self, glb, params, row, comm_id, thread_id, pid, tid, parent_item):
		super(CallTreeLevelTwoItem, self).__init__(glb, params, row, comm_id, thread_id, 0, 0, 0, 0, 0, 0, parent_item)
		if self.params.have_ipc:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [str(pid) + ":" + str(tid), "", "", "", "", "", ""]
		self.dbid = thread_id

	def Select(self):
		super(CallTreeLevelTwoItem, self).Select()
		for child_item in self.child_items:
			self.time += child_item.time
			self.insn_cnt += child_item.insn_cnt
			self.cyc_cnt += child_item.cyc_cnt
			self.branch_count += child_item.branch_count
		for child_item in self.child_items:
			child_item.data[4] = PercentToOneDP(child_item.time, self.time)
			if self.params.have_ipc:
				child_item.data[6] = PercentToOneDP(child_item.insn_cnt, self.insn_cnt)
				child_item.data[8] = PercentToOneDP(child_item.cyc_cnt, self.cyc_cnt)
				child_item.data[11] = PercentToOneDP(child_item.branch_count, self.branch_count)
			else:
				child_item.data[6] = PercentToOneDP(child_item.branch_count, self.branch_count)

# Call tree data model level one item

class CallTreeLevelOneItem(CallGraphLevelItemBase):

	def __init__(self, glb, params, row, comm_id, comm, parent_item):
		super(CallTreeLevelOneItem, self).__init__(glb, params, row, parent_item)
		if self.params.have_ipc:
			self.data = [comm, "", "", "", "", "", "", "", "", "", "", ""]
		else:
			self.data = [comm, "", "", "", "", "", ""]
		self.dbid = comm_id

	def Select(self):
		self.query_done = True
		query = QSqlQuery(self.glb.db)
		QueryExec(query, "SELECT thread_id, pid, tid"
					" FROM comm_threads"
					" INNER JOIN threads ON thread_id = threads.id"
					" WHERE comm_id = " + str(self.dbid))
		while query.next():
			child_item = CallTreeLevelTwoItem(self.glb, self.params, self.child_count, self.dbid, query.value(0), query.value(1), query.value(2), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call tree data model root item

class CallTreeRootItem(CallGraphLevelItemBase):

	def __init__(self, glb, params):
		super(CallTreeRootItem, self).__init__(glb, params, 0, None)
		self.dbid = 0
		self.query_done = True
		if_has_calls = ""
		if IsSelectable(glb.db, "comms", columns = "has_calls"):
			if_has_calls = " WHERE has_calls = " + glb.dbref.TRUE
		query = QSqlQuery(glb.db)
		QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls)
		while query.next():
			if not query.value(0):
				continue
			child_item = CallTreeLevelOneItem(glb, params, self.child_count, query.value(0), query.value(1), self)
			self.child_items.append(child_item)
			self.child_count += 1

# Call Tree data model

class CallTreeModel(CallGraphModelBase):

	def __init__(self, glb, parent=None):
		super(CallTreeModel, self).__init__(glb, parent)

	def GetRoot(self):
		return CallTreeRootItem(self.glb, self.params)

	def columnCount(self, parent=None):
		if self.params.have_ipc:
			return 12
		else:
			return 7

	def columnHeader(self, column):
		if self.params.have_ipc:
			headers = ["Call Path", "Object", "Call Time", "Time (ns) ", "Time (%) ", "Insn Cnt", "Insn Cnt (%)", "Cyc Cnt", "Cyc Cnt (%)", "IPC", "Branch Count ", "Branch Count (%) "]
		else:
			headers = ["Call Path", "Object", "Call Time", "Time (ns) ", "Time (%) ", "Branch Count ", "Branch Count (%) "]
		return headers[column]

	def columnAlignment(self, column):
		if self.params.have_ipc:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		else:
			alignment = [ Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight, Qt.AlignRight ]
		return alignment[column]

	def DoFindSelect(self, query, match):
		QueryExec(query, "SELECT calls.id, comm_id, thread_id"
						" FROM calls"
						" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
						" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
						" WHERE calls.id <> 0"
						" AND symbols.name" + match +
						" ORDER BY comm_id, thread_id, call_time, calls.id")

	def FindPath(self, query):
		# Turn the query result into a list of ids that the tree view can walk
		# to open the tree at the right place.
		ids = []
		parent_id = query.value(0)
		while parent_id:
			ids.insert(0, parent_id)
			q2 = QSqlQuery(self.glb.db)
			QueryExec(q2, "SELECT parent_id"
					" FROM calls"
					" WHERE id = " + str(parent_id))
			if not q2.next():
				break
			parent_id = q2.value(0)
		ids.insert(0, query.value(2))
		ids.insert(0, query.value(1))
		return ids

# Vertical layout

class HBoxLayout(QHBoxLayout):

	def __init__(self, *children):
		super(HBoxLayout, self).__init__()

		self.layout().setContentsMargins(0, 0, 0, 0)
		for child in children:
			if child.isWidgetType():
				self.layout().addWidget(child)
			else:
				self.layout().addLayout(child)

# Horizontal layout

class VBoxLayout(QVBoxLayout):

	def __init__(self, *children):
		super(VBoxLayout, self).__init__()

		self.layout().setContentsMargins(0, 0, 0, 0)
		for child in children:
			if child.isWidgetType():
				self.layout().addWidget(child)
			else:
				self.layout().addLayout(child)

# Vertical layout widget

class VBox():

	def __init__(self, *children):
		self.vbox = QWidget()
		self.vbox.setLayout(VBoxLayout(*children))

	def Widget(self):
		return self.vbox

# Tree window base

class TreeWindowBase(QMdiSubWindow):

	def __init__(self, parent=None):
		super(TreeWindowBase, self).__init__(parent)

		self.model = None
		self.find_bar = None

		self.view = QTreeView()
		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
		self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard

		self.context_menu = TreeContextMenu(self.view)

	def DisplayFound(self, ids):
		if not len(ids):
			return False
		parent = QModelIndex()
		for dbid in ids:
			found = False
			n = self.model.rowCount(parent)
			for row in xrange(n):
				child = self.model.index(row, 0, parent)
				if child.internalPointer().dbid == dbid:
					found = True
					self.view.setExpanded(parent, True)
					self.view.setCurrentIndex(child)
					parent = child
					break
			if not found:
				break
		return found

	def Find(self, value, direction, pattern, context):
		self.view.setFocus()
		self.find_bar.Busy()
		self.model.Find(value, direction, pattern, context, self.FindDone)

	def FindDone(self, ids):
		found = True
		if not self.DisplayFound(ids):
			found = False
		self.find_bar.Idle()
		if not found:
			self.find_bar.NotFound()


# Context-sensitive call graph window

class CallGraphWindow(TreeWindowBase):

	def __init__(self, glb, parent=None):
		super(CallGraphWindow, self).__init__(parent)

		self.model = LookupCreateModel("Context-Sensitive Call Graph", lambda x=glb: CallGraphModel(x))

		self.view.setModel(self.model)

		for c, w in ((0, 250), (1, 100), (2, 60), (3, 70), (4, 70), (5, 100)):
			self.view.setColumnWidth(c, w)

		self.find_bar = FindBar(self, self)

		self.vbox = VBox(self.view, self.find_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, "Context-Sensitive Call Graph")

# Call tree window

class CallTreeWindow(TreeWindowBase):

	def __init__(self, glb, parent=None, thread_at_time=None):
		super(CallTreeWindow, self).__init__(parent)

		self.model = LookupCreateModel("Call Tree", lambda x=glb: CallTreeModel(x))

		self.view.setModel(self.model)

		for c, w in ((0, 230), (1, 100), (2, 100), (3, 70), (4, 70), (5, 100)):
			self.view.setColumnWidth(c, w)

		self.find_bar = FindBar(self, self)

		self.vbox = VBox(self.view, self.find_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, "Call Tree")

		if thread_at_time:
			self.DisplayThreadAtTime(*thread_at_time)

	def DisplayThreadAtTime(self, comm_id, thread_id, time):
		parent = QModelIndex()
		for dbid in (comm_id, thread_id):
			found = False
			n = self.model.rowCount(parent)
			for row in xrange(n):
				child = self.model.index(row, 0, parent)
				if child.internalPointer().dbid == dbid:
					found = True
					self.view.setExpanded(parent, True)
					self.view.setCurrentIndex(child)
					parent = child
					break
			if not found:
				return
		found = False
		while True:
			n = self.model.rowCount(parent)
			if not n:
				return
			last_child = None
			for row in xrange(n):
				self.view.setExpanded(parent, True)
				child = self.model.index(row, 0, parent)
				child_call_time = child.internalPointer().call_time
				if child_call_time < time:
					last_child = child
				elif child_call_time == time:
					self.view.setCurrentIndex(child)
					return
				elif child_call_time > time:
					break
			if not last_child:
				if not found:
					child = self.model.index(0, 0, parent)
					self.view.setExpanded(parent, True)
					self.view.setCurrentIndex(child)
				return
			found = True
			self.view.setExpanded(parent, True)
			self.view.setCurrentIndex(last_child)
			parent = last_child

# ExecComm() gets the comm_id of the command string that was set when the process exec'd i.e. the program name

def ExecComm(db, thread_id, time):
	query = QSqlQuery(db)
	QueryExec(query, "SELECT comm_threads.comm_id, comms.c_time, comms.exec_flag"
				" FROM comm_threads"
				" INNER JOIN comms ON comms.id = comm_threads.comm_id"
				" WHERE comm_threads.thread_id = " + str(thread_id) +
				" ORDER BY comms.c_time, comms.id")
	first = None
	last = None
	while query.next():
		if first is None:
			first = query.value(0)
		if query.value(2) and Decimal(query.value(1)) <= Decimal(time):
			last = query.value(0)
	if not(last is None):
		return last
	return first

# Container for (x, y) data

class XY():
	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y

	def __str__(self):
		return "XY({}, {})".format(str(self.x), str(self.y))

# Container for sub-range data

class Subrange():
	def __init__(self, lo=0, hi=0):
		self.lo = lo
		self.hi = hi

	def __str__(self):
		return "Subrange({}, {})".format(str(self.lo), str(self.hi))

# Graph data region base class

class GraphDataRegion(object):

	def __init__(self, key, title = "", ordinal = ""):
		self.key = key
		self.title = title
		self.ordinal = ordinal

# Function to sort GraphDataRegion

def GraphDataRegionOrdinal(data_region):
	return data_region.ordinal

# Attributes for a graph region

class GraphRegionAttribute():

	def __init__(self, colour):
		self.colour = colour

# Switch graph data region represents a task

class SwitchGraphDataRegion(GraphDataRegion):

	def __init__(self, key, exec_comm_id, pid, tid, comm, thread_id, comm_id):
		super(SwitchGraphDataRegion, self).__init__(key)

		self.title = str(pid) + " / " + str(tid) + " " + comm
		# Order graph legend within exec comm by pid / tid / time
		self.ordinal = str(pid).rjust(16) + str(exec_comm_id).rjust(8) + str(tid).rjust(16)
		self.exec_comm_id = exec_comm_id
		self.pid = pid
		self.tid = tid
		self.comm = comm
		self.thread_id = thread_id
		self.comm_id = comm_id

# Graph data point

class GraphDataPoint():

	def __init__(self, data, index, x, y, altx=None, alty=None, hregion=None, vregion=None):
		self.data = data
		self.index = index
		self.x = x
		self.y = y
		self.altx = altx
		self.alty = alty
		self.hregion = hregion
		self.vregion = vregion

# Graph data (single graph) base class

class GraphData(object):

	def __init__(self, collection, xbase=Decimal(0), ybase=Decimal(0)):
		self.collection = collection
		self.points = []
		self.xbase = xbase
		self.ybase = ybase
		self.title = ""

	def AddPoint(self, x, y, altx=None, alty=None, hregion=None, vregion=None):
		index = len(self.points)

		x = float(Decimal(x) - self.xbase)
		y = float(Decimal(y) - self.ybase)

		self.points.append(GraphDataPoint(self, index, x, y, altx, alty, hregion, vregion))

	def XToData(self, x):
		return Decimal(x) + self.xbase

	def YToData(self, y):
		return Decimal(y) + self.ybase

# Switch graph data (for one CPU)

class SwitchGraphData(GraphData):

	def __init__(self, db, collection, cpu, xbase):
		super(SwitchGraphData, self).__init__(collection, xbase)

		self.cpu = cpu
		self.title = "CPU " + str(cpu)
		self.SelectSwitches(db)

	def SelectComms(self, db, thread_id, last_comm_id, start_time, end_time):
		query = QSqlQuery(db)
		QueryExec(query, "SELECT id, c_time"
					" FROM comms"
					" WHERE c_thread_id = " + str(thread_id) +
					"   AND exec_flag = " + self.collection.glb.dbref.TRUE +
					"   AND c_time >= " + str(start_time) +
					"   AND c_time <= " + str(end_time) +
					" ORDER BY c_time, id")
		while query.next():
			comm_id = query.value(0)
			if comm_id == last_comm_id:
				continue
			time = query.value(1)
			hregion = self.HRegion(db, thread_id, comm_id, time)
			self.AddPoint(time, 1000, None, None, hregion)

	def SelectSwitches(self, db):
		last_time = None
		last_comm_id = None
		last_thread_id = None
		query = QSqlQuery(db)
		QueryExec(query, "SELECT time, thread_out_id, thread_in_id, comm_out_id, comm_in_id, flags"
					" FROM context_switches"
					" WHERE machine_id = " + str(self.collection.machine_id) +
					"   AND cpu = " + str(self.cpu) +
					" ORDER BY time, id")
		while query.next():
			flags = int(query.value(5))
			if flags & 1:
				# Schedule-out: detect and add exec's
				if last_thread_id == query.value(1) and last_comm_id is not None and last_comm_id != query.value(3):
					self.SelectComms(db, last_thread_id, last_comm_id, last_time, query.value(0))
				continue
			# Schedule-in: add data point
			if len(self.points) == 0:
				start_time = self.collection.glb.StartTime(self.collection.machine_id)
				hregion = self.HRegion(db, query.value(1), query.value(3), start_time)
				self.AddPoint(start_time, 1000, None, None, hregion)
			time = query.value(0)
			comm_id = query.value(4)
			thread_id = query.value(2)
			hregion = self.HRegion(db, thread_id, comm_id, time)
			self.AddPoint(time, 1000, None, None, hregion)
			last_time = time
			last_comm_id = comm_id
			last_thread_id = thread_id

	def NewHRegion(self, db, key, thread_id, comm_id, time):
		exec_comm_id = ExecComm(db, thread_id, time)
		query = QSqlQuery(db)
		QueryExec(query, "SELECT pid, tid FROM threads WHERE id = " + str(thread_id))
		if query.next():
			pid = query.value(0)
			tid = query.value(1)
		else:
			pid = -1
			tid = -1
		query = QSqlQuery(db)
		QueryExec(query, "SELECT comm FROM comms WHERE id = " + str(comm_id))
		if query.next():
			comm = query.value(0)
		else:
			comm = ""
		return SwitchGraphDataRegion(key, exec_comm_id, pid, tid, comm, thread_id, comm_id)

	def HRegion(self, db, thread_id, comm_id, time):
		key = str(thread_id) + ":" + str(comm_id)
		hregion = self.collection.LookupHRegion(key)
		if hregion is None:
			hregion = self.NewHRegion(db, key, thread_id, comm_id, time)
			self.collection.AddHRegion(key, hregion)
		return hregion

# Graph data collection (multiple related graphs) base class

class GraphDataCollection(object):

	def __init__(self, glb):
		self.glb = glb
		self.data = []
		self.hregions = {}
		self.xrangelo = None
		self.xrangehi = None
		self.yrangelo = None
		self.yrangehi = None
		self.dp = XY(0, 0)

	def AddGraphData(self, data):
		self.data.append(data)

	def LookupHRegion(self, key):
		if key in self.hregions:
			return self.hregions[key]
		return None

	def AddHRegion(self, key, hregion):
		self.hregions[key] = hregion

# Switch graph data collection (SwitchGraphData for each CPU)

class SwitchGraphDataCollection(GraphDataCollection):

	def __init__(self, glb, db, machine_id):
		super(SwitchGraphDataCollection, self).__init__(glb)

		self.machine_id = machine_id
		self.cpus = self.SelectCPUs(db)

		self.xrangelo = glb.StartTime(machine_id)
		self.xrangehi = glb.FinishTime(machine_id)

		self.yrangelo = Decimal(0)
		self.yrangehi = Decimal(1000)

		for cpu in self.cpus:
			self.AddGraphData(SwitchGraphData(db, self, cpu, self.xrangelo))

	def SelectCPUs(self, db):
		cpus = []
		query = QSqlQuery(db)
		QueryExec(query, "SELECT DISTINCT cpu"
					" FROM context_switches"
					" WHERE machine_id = " + str(self.machine_id))
		while query.next():
			cpus.append(int(query.value(0)))
		return sorted(cpus)

# Switch graph data graphics item displays the graphed data

class SwitchGraphDataGraphicsItem(QGraphicsItem):

	def __init__(self, data, graph_width, graph_height, attrs, event_handler, parent=None):
		super(SwitchGraphDataGraphicsItem, self).__init__(parent)

		self.data = data
		self.graph_width = graph_width
		self.graph_height = graph_height
		self.attrs = attrs
		self.event_handler = event_handler
		self.setAcceptHoverEvents(True)

	def boundingRect(self):
		return QRectF(0, 0, self.graph_width, self.graph_height)

	def PaintPoint(self, painter, last, x):
		if not(last is None or last.hregion.pid == 0 or x < self.attrs.subrange.x.lo):
			if last.x < self.attrs.subrange.x.lo:
				x0 = self.attrs.subrange.x.lo
			else:
				x0 = last.x
			if x > self.attrs.subrange.x.hi:
				x1 = self.attrs.subrange.x.hi
			else:
				x1 = x - 1
			x0 = self.attrs.XToPixel(x0)
			x1 = self.attrs.XToPixel(x1)

			y0 = self.attrs.YToPixel(last.y)

			colour = self.attrs.region_attributes[last.hregion.key].colour

			width = x1 - x0 + 1
			if width < 2:
				painter.setPen(colour)
				painter.drawLine(x0, self.graph_height - y0, x0, self.graph_height)
			else:
				painter.fillRect(x0, self.graph_height - y0, width, self.graph_height - 1, colour)

	def paint(self, painter, option, widget):
		last = None
		for point in self.data.points:
			self.PaintPoint(painter, last, point.x)
			if point.x > self.attrs.subrange.x.hi:
				break;
			last = point
		self.PaintPoint(painter, last, self.attrs.subrange.x.hi + 1)

	def BinarySearchPoint(self, target):
		lower_pos = 0
		higher_pos = len(self.data.points)
		while True:
			pos = int((lower_pos + higher_pos) / 2)
			val = self.data.points[pos].x
			if target >= val:
				lower_pos = pos
			else:
				higher_pos = pos
			if higher_pos <= lower_pos + 1:
				return lower_pos

	def XPixelToData(self, x):
		x = self.attrs.PixelToX(x)
		if x < self.data.points[0].x:
			x = 0
			pos = 0
			low = True
		else:
			pos = self.BinarySearchPoint(x)
			low = False
		return (low, pos, self.data.XToData(x))

	def EventToData(self, event):
		no_data = (None,) * 4
		if len(self.data.points) < 1:
			return no_data
		x = event.pos().x()
		if x < 0:
			return no_data
		low0, pos0, time_from = self.XPixelToData(x)
		low1, pos1, time_to = self.XPixelToData(x + 1)
		hregions = set()
		hregion_times = []
		if not low1:
			for i in xrange(pos0, pos1 + 1):
				hregion = self.data.points[i].hregion
				hregions.add(hregion)
				if i == pos0:
					time = time_from
				else:
					time = self.data.XToData(self.data.points[i].x)
				hregion_times.append((hregion, time))
		return (time_from, time_to, hregions, hregion_times)

	def hoverMoveEvent(self, event):
		time_from, time_to, hregions, hregion_times = self.EventToData(event)
		if time_from is not None:
			self.event_handler.PointEvent(self.data.cpu, time_from, time_to, hregions)

	def hoverLeaveEvent(self, event):
		self.event_handler.NoPointEvent()

	def mousePressEvent(self, event):
		if event.button() != Qt.RightButton:
			super(SwitchGraphDataGraphicsItem, self).mousePressEvent(event)
			return
		time_from, time_to, hregions, hregion_times = self.EventToData(event)
		if hregion_times:
			self.event_handler.RightClickEvent(self.data.cpu, hregion_times, event.screenPos())

# X-axis graphics item

class XAxisGraphicsItem(QGraphicsItem):

	def __init__(self, width, parent=None):
		super(XAxisGraphicsItem, self).__init__(parent)

		self.width = width
		self.max_mark_sz = 4
		self.height = self.max_mark_sz + 1

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def Step(self):
		attrs = self.parentItem().attrs
		subrange = attrs.subrange.x
		t = subrange.hi - subrange.lo
		s = (3.0 * t) / self.width
		n = 1.0
		while s > n:
			n = n * 10.0
		return n

	def PaintMarks(self, painter, at_y, lo, hi, step, i):
		attrs = self.parentItem().attrs
		x = lo
		while x <= hi:
			xp = attrs.XToPixel(x)
			if i % 10:
				if i % 5:
					sz = 1
				else:
					sz = 2
			else:
				sz = self.max_mark_sz
				i = 0
			painter.drawLine(xp, at_y, xp, at_y + sz)
			x += step
			i += 1

	def paint(self, painter, option, widget):
		# Using QPainter::drawLine(int x1, int y1, int x2, int y2) so x2 = width -1
		painter.drawLine(0, 0, self.width - 1, 0)
		n = self.Step()
		attrs = self.parentItem().attrs
		subrange = attrs.subrange.x
		if subrange.lo:
			x_offset = n - (subrange.lo % n)
		else:
			x_offset = 0.0
		x = subrange.lo + x_offset
		i = (x / n) % 10
		self.PaintMarks(painter, 0, x, subrange.hi, n, i)

	def ScaleDimensions(self):
		n = self.Step()
		attrs = self.parentItem().attrs
		lo = attrs.subrange.x.lo
		hi = (n * 10.0) + lo
		width = attrs.XToPixel(hi)
		if width > 500:
			width = 0
		return (n, lo, hi, width)

	def PaintScale(self, painter, at_x, at_y):
		n, lo, hi, width = self.ScaleDimensions()
		if not width:
			return
		painter.drawLine(at_x, at_y, at_x + width, at_y)
		self.PaintMarks(painter, at_y, lo, hi, n, 0)

	def ScaleWidth(self):
		n, lo, hi, width = self.ScaleDimensions()
		return width

	def ScaleHeight(self):
		return self.height

	def ScaleUnit(self):
		return self.Step() * 10

# Scale graphics item base class

class ScaleGraphicsItem(QGraphicsItem):

	def __init__(self, axis, parent=None):
		super(ScaleGraphicsItem, self).__init__(parent)
		self.axis = axis

	def boundingRect(self):
		scale_width = self.axis.ScaleWidth()
		if not scale_width:
			return QRectF()
		return QRectF(0, 0, self.axis.ScaleWidth() + 100, self.axis.ScaleHeight())

	def paint(self, painter, option, widget):
		scale_width = self.axis.ScaleWidth()
		if not scale_width:
			return
		self.axis.PaintScale(painter, 0, 5)
		x = scale_width + 4
		painter.drawText(QPointF(x, 10), self.Text())

	def Unit(self):
		return self.axis.ScaleUnit()

	def Text(self):
		return ""

# Switch graph scale graphics item

class SwitchScaleGraphicsItem(ScaleGraphicsItem):

	def __init__(self, axis, parent=None):
		super(SwitchScaleGraphicsItem, self).__init__(axis, parent)

	def Text(self):
		unit = self.Unit()
		if unit >= 1000000000:
			unit = int(unit / 1000000000)
			us = "s"
		elif unit >= 1000000:
			unit = int(unit / 1000000)
			us = "ms"
		elif unit >= 1000:
			unit = int(unit / 1000)
			us = "us"
		else:
			unit = int(unit)
			us = "ns"
		return " = " + str(unit) + " " + us

# Switch graph graphics item contains graph title, scale, x/y-axis, and the graphed data

class SwitchGraphGraphicsItem(QGraphicsItem):

	def __init__(self, collection, data, attrs, event_handler, first, parent=None):
		super(SwitchGraphGraphicsItem, self).__init__(parent)
		self.collection = collection
		self.data = data
		self.attrs = attrs
		self.event_handler = event_handler

		margin = 20
		title_width = 50

		self.title_graphics = QGraphicsSimpleTextItem(data.title, self)

		self.title_graphics.setPos(margin, margin)
		graph_width = attrs.XToPixel(attrs.subrange.x.hi) + 1
		graph_height = attrs.YToPixel(attrs.subrange.y.hi) + 1

		self.graph_origin_x = margin + title_width + margin
		self.graph_origin_y = graph_height + margin

		x_axis_size = 1
		y_axis_size = 1
		self.yline = QGraphicsLineItem(0, 0, 0, graph_height, self)

		self.x_axis = XAxisGraphicsItem(graph_width, self)
		self.x_axis.setPos(self.graph_origin_x, self.graph_origin_y + 1)

		if first:
			self.scale_item = SwitchScaleGraphicsItem(self.x_axis, self)
			self.scale_item.setPos(self.graph_origin_x, self.graph_origin_y + 10)

		self.yline.setPos(self.graph_origin_x - y_axis_size, self.graph_origin_y - graph_height)

		self.axis_point = QGraphicsLineItem(0, 0, 0, 0, self)
		self.axis_point.setPos(self.graph_origin_x - 1, self.graph_origin_y +1)

		self.width = self.graph_origin_x + graph_width + margin
		self.height = self.graph_origin_y + margin

		self.graph = SwitchGraphDataGraphicsItem(data, graph_width, graph_height, attrs, event_handler, self)
		self.graph.setPos(self.graph_origin_x, self.graph_origin_y - graph_height)

		if parent and 'EnableRubberBand' in dir(parent):
			parent.EnableRubberBand(self.graph_origin_x, self.graph_origin_x + graph_width - 1, self)

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def paint(self, painter, option, widget):
		pass

	def RBXToPixel(self, x):
		return self.attrs.PixelToX(x - self.graph_origin_x)

	def RBXRangeToPixel(self, x0, x1):
		return (self.RBXToPixel(x0), self.RBXToPixel(x1 + 1))

	def RBPixelToTime(self, x):
		if x < self.data.points[0].x:
			return self.data.XToData(0)
		return self.data.XToData(x)

	def RBEventTimes(self, x0, x1):
		x0, x1 = self.RBXRangeToPixel(x0, x1)
		time_from = self.RBPixelToTime(x0)
		time_to = self.RBPixelToTime(x1)
		return (time_from, time_to)

	def RBEvent(self, x0, x1):
		time_from, time_to = self.RBEventTimes(x0, x1)
		self.event_handler.RangeEvent(time_from, time_to)

	def RBMoveEvent(self, x0, x1):
		if x1 < x0:
			x0, x1 = x1, x0
		self.RBEvent(x0, x1)

	def RBReleaseEvent(self, x0, x1, selection_state):
		if x1 < x0:
			x0, x1 = x1, x0
		x0, x1 = self.RBXRangeToPixel(x0, x1)
		self.event_handler.SelectEvent(x0, x1, selection_state)

# Graphics item to draw a vertical bracket (used to highlight "forward" sub-range)

class VerticalBracketGraphicsItem(QGraphicsItem):

	def __init__(self, parent=None):
		super(VerticalBracketGraphicsItem, self).__init__(parent)

		self.width = 0
		self.height = 0
		self.hide()

	def SetSize(self, width, height):
		self.width = width + 1
		self.height = height + 1

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def paint(self, painter, option, widget):
		colour = QColor(255, 255, 0, 32)
		painter.fillRect(0, 0, self.width, self.height, colour)
		x1 = self.width - 1
		y1 = self.height - 1
		painter.drawLine(0, 0, x1, 0)
		painter.drawLine(0, 0, 0, 3)
		painter.drawLine(x1, 0, x1, 3)
		painter.drawLine(0, y1, x1, y1)
		painter.drawLine(0, y1, 0, y1 - 3)
		painter.drawLine(x1, y1, x1, y1 - 3)

# Graphics item to contain graphs arranged vertically

class VertcalGraphSetGraphicsItem(QGraphicsItem):

	def __init__(self, collection, attrs, event_handler, child_class, parent=None):
		super(VertcalGraphSetGraphicsItem, self).__init__(parent)

		self.collection = collection

		self.top = 10

		self.width = 0
		self.height = self.top

		self.rubber_band = None
		self.rb_enabled = False

		first = True
		for data in collection.data:
			child = child_class(collection, data, attrs, event_handler, first, self)
			child.setPos(0, self.height + 1)
			rect = child.boundingRect()
			if rect.right() > self.width:
				self.width = rect.right()
			self.height = self.height + rect.bottom() + 1
			first = False

		self.bracket = VerticalBracketGraphicsItem(self)

	def EnableRubberBand(self, xlo, xhi, rb_event_handler):
		if self.rb_enabled:
			return
		self.rb_enabled = True
		self.rb_in_view = False
		self.setAcceptedMouseButtons(Qt.LeftButton)
		self.rb_xlo = xlo
		self.rb_xhi = xhi
		self.rb_event_handler = rb_event_handler
		self.mousePressEvent = self.MousePressEvent
		self.mouseMoveEvent = self.MouseMoveEvent
		self.mouseReleaseEvent = self.MouseReleaseEvent

	def boundingRect(self):
		return QRectF(0, 0, self.width, self.height)

	def paint(self, painter, option, widget):
		pass

	def RubberBandParent(self):
		scene = self.scene()
		view = scene.views()[0]
		viewport = view.viewport()
		return viewport

	def RubberBandSetGeometry(self, rect):
		scene_rectf = self.mapRectToScene(QRectF(rect))
		scene = self.scene()
		view = scene.views()[0]
		poly = view.mapFromScene(scene_rectf)
		self.rubber_band.setGeometry(poly.boundingRect())

	def SetSelection(self, selection_state):
		if self.rubber_band:
			if selection_state:
				self.RubberBandSetGeometry(selection_state)
				self.rubber_band.show()
			else:
				self.rubber_band.hide()

	def SetBracket(self, rect):
		if rect:
			x, y, width, height = rect.x(), rect.y(), rect.width(), rect.height()
			self.bracket.setPos(x, y)
			self.bracket.SetSize(width, height)
			self.bracket.show()
		else:
			self.bracket.hide()

	def RubberBandX(self, event):
		x = event.pos().toPoint().x()
		if x < self.rb_xlo:
			x = self.rb_xlo
		elif x > self.rb_xhi:
			x = self.rb_xhi
		else:
			self.rb_in_view = True
		return x

	def RubberBandRect(self, x):
		if self.rb_origin.x() <= x:
			width = x - self.rb_origin.x()
			rect = QRect(self.rb_origin, QSize(width, self.height))
		else:
			width = self.rb_origin.x() - x
			top_left = QPoint(self.rb_origin.x() - width, self.rb_origin.y())
			rect = QRect(top_left, QSize(width, self.height))
		return rect

	def MousePressEvent(self, event):
		self.rb_in_view = False
		x = self.RubberBandX(event)
		self.rb_origin = QPoint(x, self.top)
		if self.rubber_band is None:
			self.rubber_band = QRubberBand(QRubberBand.Rectangle, self.RubberBandParent())
		self.RubberBandSetGeometry(QRect(self.rb_origin, QSize(0, self.height)))
		if self.rb_in_view:
			self.rubber_band.show()
			self.rb_event_handler.RBMoveEvent(x, x)
		else:
			self.rubber_band.hide()

	def MouseMoveEvent(self, event):
		x = self.RubberBandX(event)
		rect = self.RubberBandRect(x)
		self.RubberBandSetGeometry(rect)
		if self.rb_in_view:
			self.rubber_band.show()
			self.rb_event_handler.RBMoveEvent(self.rb_origin.x(), x)

	def MouseReleaseEvent(self, event):
		x = self.RubberBandX(event)
		if self.rb_in_view:
			selection_state = self.RubberBandRect(x)
		else:
			selection_state = None
		self.rb_event_handler.RBReleaseEvent(self.rb_origin.x(), x, selection_state)

# Switch graph legend data model

class SwitchGraphLegendModel(QAbstractTableModel):

	def __init__(self, collection, region_attributes, parent=None):
		super(SwitchGraphLegendModel, self).__init__(parent)

		self.region_attributes = region_attributes

		self.child_items = sorted(collection.hregions.values(), key=GraphDataRegionOrdinal)
		self.child_count = len(self.child_items)

		self.highlight_set = set()

		self.column_headers = ("pid", "tid", "comm")

	def rowCount(self, parent):
		return self.child_count

	def headerData(self, section, orientation, role):
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.columnHeader(section)

	def index(self, row, column, parent):
		return self.createIndex(row, column, self.child_items[row])

	def columnCount(self, parent=None):
		return len(self.column_headers)

	def columnHeader(self, column):
		return self.column_headers[column]

	def data(self, index, role):
		if role == Qt.BackgroundRole:
			child = self.child_items[index.row()]
			if child in self.highlight_set:
				return self.region_attributes[child.key].colour
			return None
		if role == Qt.ForegroundRole:
			child = self.child_items[index.row()]
			if child in self.highlight_set:
				return QColor(255, 255, 255)
			return self.region_attributes[child.key].colour
		if role != Qt.DisplayRole:
			return None
		hregion = self.child_items[index.row()]
		col = index.column()
		if col == 0:
			return hregion.pid
		if col == 1:
			return hregion.tid
		if col == 2:
			return hregion.comm
		return None

	def SetHighlight(self, row, set_highlight):
		child = self.child_items[row]
		top_left = self.createIndex(row, 0, child)
		bottom_right = self.createIndex(row, len(self.column_headers) - 1, child)
		self.dataChanged.emit(top_left, bottom_right)

	def Highlight(self, highlight_set):
		for row in xrange(self.child_count):
			child = self.child_items[row]
			if child in self.highlight_set:
				if child not in highlight_set:
					self.SetHighlight(row, False)
			elif child in highlight_set:
				self.SetHighlight(row, True)
		self.highlight_set = highlight_set

# Switch graph legend is a table

class SwitchGraphLegend(QWidget):

	def __init__(self, collection, region_attributes, parent=None):
		super(SwitchGraphLegend, self).__init__(parent)

		self.data_model = SwitchGraphLegendModel(collection, region_attributes)

		self.model = QSortFilterProxyModel()
		self.model.setSourceModel(self.data_model)

		self.view = QTableView()
		self.view.setModel(self.model)
		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.view.verticalHeader().setVisible(False)
		self.view.sortByColumn(-1, Qt.AscendingOrder)
		self.view.setSortingEnabled(True)
		self.view.resizeColumnsToContents()
		self.view.resizeRowsToContents()

		self.vbox = VBoxLayout(self.view)
		self.setLayout(self.vbox)

		sz1 = self.view.columnWidth(0) + self.view.columnWidth(1) + self.view.columnWidth(2) + 2
		sz1 = sz1 + self.view.verticalScrollBar().sizeHint().width()
		self.saved_size = sz1

	def resizeEvent(self, event):
		self.saved_size = self.size().width()
		super(SwitchGraphLegend, self).resizeEvent(event)

	def Highlight(self, highlight_set):
		self.data_model.Highlight(highlight_set)
		self.update()

	def changeEvent(self, event):
		if event.type() == QEvent.FontChange:
			self.view.resizeRowsToContents()
			self.view.resizeColumnsToContents()
			# Need to resize rows again after column resize
			self.view.resizeRowsToContents()
		super(SwitchGraphLegend, self).changeEvent(event)

# Random colour generation

def RGBColourTooLight(r, g, b):
	if g > 230:
		return True
	if g <= 160:
		return False
	if r <= 180 and g <= 180:
		return False
	if r < 60:
		return False
	return True

def GenerateColours(x):
	cs = [0]
	for i in xrange(1, x):
		cs.append(int((255.0 / i) + 0.5))
	colours = []
	for r in cs:
		for g in cs:
			for b in cs:
				# Exclude black and colours that look too light against a white background
				if (r, g, b) == (0, 0, 0) or RGBColourTooLight(r, g, b):
					continue
				colours.append(QColor(r, g, b))
	return colours

def GenerateNColours(n):
	for x in xrange(2, n + 2):
		colours = GenerateColours(x)
		if len(colours) >= n:
			return colours
	return []

def GenerateNRandomColours(n, seed):
	colours = GenerateNColours(n)
	random.seed(seed)
	random.shuffle(colours)
	return colours

# Graph attributes, in particular the scale and subrange that change when zooming

class GraphAttributes():

	def __init__(self, scale, subrange, region_attributes, dp):
		self.scale = scale
		self.subrange = subrange
		self.region_attributes = region_attributes
		# Rounding avoids errors due to finite floating point precision
		self.dp = dp	# data decimal places
		self.Update()

	def XToPixel(self, x):
		return int(round((x - self.subrange.x.lo) * self.scale.x, self.pdp.x))

	def YToPixel(self, y):
		return int(round((y - self.subrange.y.lo) * self.scale.y, self.pdp.y))

	def PixelToXRounded(self, px):
		return round((round(px, 0) / self.scale.x), self.dp.x) + self.subrange.x.lo

	def PixelToYRounded(self, py):
		return round((round(py, 0) / self.scale.y), self.dp.y) + self.subrange.y.lo

	def PixelToX(self, px):
		x = self.PixelToXRounded(px)
		if self.pdp.x == 0:
			rt = self.XToPixel(x)
			if rt > px:
				return x - 1
		return x

	def PixelToY(self, py):
		y = self.PixelToYRounded(py)
		if self.pdp.y == 0:
			rt = self.YToPixel(y)
			if rt > py:
				return y - 1
		return y

	def ToPDP(self, dp, scale):
		# Calculate pixel decimal places:
		#    (10 ** dp) is the minimum delta in the data
		#    scale it to get the minimum delta in pixels
		#    log10 gives the number of decimals places negatively
		#    subtrace 1 to divide by 10
		#    round to the lower negative number
		#    change the sign to get the number of decimals positively
		x = math.log10((10 ** dp) * scale)
		if x < 0:
			x -= 1
			x = -int(math.floor(x) - 0.1)
		else:
			x = 0
		return x

	def Update(self):
		x = self.ToPDP(self.dp.x, self.scale.x)
		y = self.ToPDP(self.dp.y, self.scale.y)
		self.pdp = XY(x, y) # pixel decimal places

# Switch graph splitter which divides the CPU graphs from the legend

class SwitchGraphSplitter(QSplitter):

	def __init__(self, parent=None):
		super(SwitchGraphSplitter, self).__init__(parent)

		self.first_time = False

	def resizeEvent(self, ev):
		if self.first_time:
			self.first_time = False
			sz1 = self.widget(1).view.columnWidth(0) + self.widget(1).view.columnWidth(1) + self.widget(1).view.columnWidth(2) + 2
			sz1 = sz1 + self.widget(1).view.verticalScrollBar().sizeHint().width()
			sz0 = self.size().width() - self.handleWidth() - sz1
			self.setSizes([sz0, sz1])
		elif not(self.widget(1).saved_size is None):
			sz1 = self.widget(1).saved_size
			sz0 = self.size().width() - self.handleWidth() - sz1
			self.setSizes([sz0, sz1])
		super(SwitchGraphSplitter, self).resizeEvent(ev)

# Graph widget base class

class GraphWidget(QWidget):

	graph_title_changed = Signal(object)

	def __init__(self, parent=None):
		super(GraphWidget, self).__init__(parent)

	def GraphTitleChanged(self, title):
		self.graph_title_changed.emit(title)

	def Title(self):
		return ""

# Display time in s, ms, us or ns

def ToTimeStr(val):
	val = Decimal(val)
	if val >= 1000000000:
		return "{} s".format((val / 1000000000).quantize(Decimal("0.000000001")))
	if val >= 1000000:
		return "{} ms".format((val / 1000000).quantize(Decimal("0.000001")))
	if val >= 1000:
		return "{} us".format((val / 1000).quantize(Decimal("0.001")))
	return "{} ns".format(val.quantize(Decimal("1")))

# Switch (i.e. context switch i.e. Time Chart by CPU) graph widget which contains the CPU graphs and the legend and control buttons

class SwitchGraphWidget(GraphWidget):

	def __init__(self, glb, collection, parent=None):
		super(SwitchGraphWidget, self).__init__(parent)

		self.glb = glb
		self.collection = collection

		self.back_state = []
		self.forward_state = []
		self.selection_state = (None, None)
		self.fwd_rect = None
		self.start_time = self.glb.StartTime(collection.machine_id)

		i = 0
		hregions = collection.hregions.values()
		colours = GenerateNRandomColours(len(hregions), 1013)
		region_attributes = {}
		for hregion in hregions:
			if hregion.pid == 0 and hregion.tid == 0:
				region_attributes[hregion.key] = GraphRegionAttribute(QColor(0, 0, 0))
			else:
				region_attributes[hregion.key] = GraphRegionAttribute(colours[i])
				i = i + 1

		# Default to entire range
		xsubrange = Subrange(0.0, float(collection.xrangehi - collection.xrangelo) + 1.0)
		ysubrange = Subrange(0.0, float(collection.yrangehi - collection.yrangelo) + 1.0)
		subrange = XY(xsubrange, ysubrange)

		scale = self.GetScaleForRange(subrange)

		self.attrs = GraphAttributes(scale, subrange, region_attributes, collection.dp)

		self.item = VertcalGraphSetGraphicsItem(collection, self.attrs, self, SwitchGraphGraphicsItem)

		self.scene = QGraphicsScene()
		self.scene.addItem(self.item)

		self.view = QGraphicsView(self.scene)
		self.view.centerOn(0, 0)
		self.view.setAlignment(Qt.AlignLeft | Qt.AlignTop)

		self.legend = SwitchGraphLegend(collection, region_attributes)

		self.splitter = SwitchGraphSplitter()
		self.splitter.addWidget(self.view)
		self.splitter.addWidget(self.legend)

		self.point_label = QLabel("")
		self.point_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)

		self.back_button = QToolButton()
		self.back_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowLeft))
		self.back_button.setDisabled(True)
		self.back_button.released.connect(lambda: self.Back())

		self.forward_button = QToolButton()
		self.forward_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowRight))
		self.forward_button.setDisabled(True)
		self.forward_button.released.connect(lambda: self.Forward())

		self.zoom_button = QToolButton()
		self.zoom_button.setText("Zoom")
		self.zoom_button.setDisabled(True)
		self.zoom_button.released.connect(lambda: self.Zoom())

		self.hbox = HBoxLayout(self.back_button, self.forward_button, self.zoom_button, self.point_label)

		self.vbox = VBoxLayout(self.splitter, self.hbox)

		self.setLayout(self.vbox)

	def GetScaleForRangeX(self, xsubrange):
		# Default graph 1000 pixels wide
		dflt = 1000.0
		r = xsubrange.hi - xsubrange.lo
		return dflt / r

	def GetScaleForRangeY(self, ysubrange):
		# Default graph 50 pixels high
		dflt = 50.0
		r = ysubrange.hi - ysubrange.lo
		return dflt / r

	def GetScaleForRange(self, subrange):
		# Default graph 1000 pixels wide, 50 pixels high
		xscale = self.GetScaleForRangeX(subrange.x)
		yscale = self.GetScaleForRangeY(subrange.y)
		return XY(xscale, yscale)

	def PointEvent(self, cpu, time_from, time_to, hregions):
		text = "CPU: " + str(cpu)
		time_from = time_from.quantize(Decimal(1))
		rel_time_from = time_from - self.glb.StartTime(self.collection.machine_id)
		text = text + " Time: " + str(time_from) + " (+" + ToTimeStr(rel_time_from) + ")"
		self.point_label.setText(text)
		self.legend.Highlight(hregions)

	def RightClickEvent(self, cpu, hregion_times, pos):
		if not IsSelectable(self.glb.db, "calls", "WHERE parent_id >= 0"):
			return
		menu = QMenu(self.view)
		for hregion, time in hregion_times:
			thread_at_time = (hregion.exec_comm_id, hregion.thread_id, time)
			menu_text = "Show Call Tree for {} {}:{} at {}".format(hregion.comm, hregion.pid, hregion.tid, time)
			menu.addAction(CreateAction(menu_text, "Show Call Tree", lambda a=None, args=thread_at_time: self.RightClickSelect(args), self.view))
		menu.exec_(pos)

	def RightClickSelect(self, args):
		CallTreeWindow(self.glb, self.glb.mainwindow, thread_at_time=args)

	def NoPointEvent(self):
		self.point_label.setText("")
		self.legend.Highlight({})

	def RangeEvent(self, time_from, time_to):
		time_from = time_from.quantize(Decimal(1))
		time_to = time_to.quantize(Decimal(1))
		if time_to <= time_from:
			self.point_label.setText("")
			return
		rel_time_from = time_from - self.start_time
		rel_time_to = time_to - self.start_time
		text = " Time: " + str(time_from) + " (+" + ToTimeStr(rel_time_from) + ") to: " + str(time_to) + " (+" + ToTimeStr(rel_time_to) + ")"
		text = text + " duration: " + ToTimeStr(time_to - time_from)
		self.point_label.setText(text)

	def BackState(self):
		return (self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect)

	def PushBackState(self):
		state = copy.deepcopy(self.BackState())
		self.back_state.append(state)
		self.back_button.setEnabled(True)

	def PopBackState(self):
		self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect = self.back_state.pop()
		self.attrs.Update()
		if not self.back_state:
			self.back_button.setDisabled(True)

	def PushForwardState(self):
		state = copy.deepcopy(self.BackState())
		self.forward_state.append(state)
		self.forward_button.setEnabled(True)

	def PopForwardState(self):
		self.attrs.subrange, self.attrs.scale, self.selection_state, self.fwd_rect = self.forward_state.pop()
		self.attrs.Update()
		if not self.forward_state:
			self.forward_button.setDisabled(True)

	def Title(self):
		time_from = self.collection.xrangelo + Decimal(self.attrs.subrange.x.lo)
		time_to = self.collection.xrangelo + Decimal(self.attrs.subrange.x.hi)
		rel_time_from = time_from - self.start_time
		rel_time_to = time_to - self.start_time
		title = "+" + ToTimeStr(rel_time_from) + " to +" + ToTimeStr(rel_time_to)
		title = title + " (" + ToTimeStr(time_to - time_from) + ")"
		return title

	def Update(self):
		selected_subrange, selection_state = self.selection_state
		self.item.SetSelection(selection_state)
		self.item.SetBracket(self.fwd_rect)
		self.zoom_button.setDisabled(selected_subrange is None)
		self.GraphTitleChanged(self.Title())
		self.item.update(self.item.boundingRect())

	def Back(self):
		if not self.back_state:
			return
		self.PushForwardState()
		self.PopBackState()
		self.Update()

	def Forward(self):
		if not self.forward_state:
			return
		self.PushBackState()
		self.PopForwardState()
		self.Update()

	def SelectEvent(self, x0, x1, selection_state):
		if selection_state is None:
			selected_subrange = None
		else:
			if x1 - x0 < 1.0:
				x1 += 1.0
			selected_subrange = Subrange(x0, x1)
		self.selection_state = (selected_subrange, selection_state)
		self.zoom_button.setDisabled(selected_subrange is None)

	def Zoom(self):
		selected_subrange, selection_state = self.selection_state
		if selected_subrange is None:
			return
		self.fwd_rect = selection_state
		self.item.SetSelection(None)
		self.PushBackState()
		self.attrs.subrange.x = selected_subrange
		self.forward_state = []
		self.forward_button.setDisabled(True)
		self.selection_state = (None, None)
		self.fwd_rect = None
		self.attrs.scale.x = self.GetScaleForRangeX(self.attrs.subrange.x)
		self.attrs.Update()
		self.Update()

# Slow initialization - perform non-GUI initialization in a separate thread and put up a modal message box while waiting

class SlowInitClass():

	def __init__(self, glb, title, init_fn):
		self.init_fn = init_fn
		self.done = False
		self.result = None

		self.msg_box = QMessageBox(glb.mainwindow)
		self.msg_box.setText("Initializing " + title + ". Please wait.")
		self.msg_box.setWindowTitle("Initializing " + title)
		self.msg_box.setWindowIcon(glb.mainwindow.style().standardIcon(QStyle.SP_MessageBoxInformation))

		self.init_thread = Thread(self.ThreadFn, glb)
		self.init_thread.done.connect(lambda: self.Done(), Qt.QueuedConnection)

		self.init_thread.start()

	def Done(self):
		self.msg_box.done(0)

	def ThreadFn(self, glb):
		conn_name = "SlowInitClass" + str(os.getpid())
		db, dbname = glb.dbref.Open(conn_name)
		self.result = self.init_fn(db)
		self.done = True
		return (True, 0)

	def Result(self):
		while not self.done:
			self.msg_box.exec_()
		self.init_thread.wait()
		return self.result

def SlowInit(glb, title, init_fn):
	init = SlowInitClass(glb, title, init_fn)
	return init.Result()

# Time chart by CPU window

class TimeChartByCPUWindow(QMdiSubWindow):

	def __init__(self, glb, parent=None):
		super(TimeChartByCPUWindow, self).__init__(parent)

		self.glb = glb
		self.machine_id = glb.HostMachineId()
		self.collection_name = "SwitchGraphDataCollection " + str(self.machine_id)

		collection = LookupModel(self.collection_name)
		if collection is None:
			collection = SlowInit(glb, "Time Chart", self.Init)

		self.widget = SwitchGraphWidget(glb, collection, self)
		self.view = self.widget

		self.base_title = "Time Chart by CPU"
		self.setWindowTitle(self.base_title + self.widget.Title())
		self.widget.graph_title_changed.connect(self.GraphTitleChanged)

		self.setWidget(self.widget)

		AddSubWindow(glb.mainwindow.mdi_area, self, self.windowTitle())

	def Init(self, db):
		return LookupCreateModel(self.collection_name, lambda : SwitchGraphDataCollection(self.glb, db, self.machine_id))

	def GraphTitleChanged(self, title):
		self.setWindowTitle(self.base_title + " : " + title)

# Child data item  finder

class ChildDataItemFinder():

	def __init__(self, root):
		self.root = root
		self.value, self.direction, self.pattern, self.last_value, self.last_pattern = (None,) * 5
		self.rows = []
		self.pos = 0

	def FindSelect(self):
		self.rows = []
		if self.pattern:
			pattern = re.compile(self.value)
			for child in self.root.child_items:
				for column_data in child.data:
					if re.search(pattern, str(column_data)) is not None:
						self.rows.append(child.row)
						break
		else:
			for child in self.root.child_items:
				for column_data in child.data:
					if self.value in str(column_data):
						self.rows.append(child.row)
						break

	def FindValue(self):
		self.pos = 0
		if self.last_value != self.value or self.pattern != self.last_pattern:
			self.FindSelect()
		if not len(self.rows):
			return -1
		return self.rows[self.pos]

	def FindThread(self):
		if self.direction == 0 or self.value != self.last_value or self.pattern != self.last_pattern:
			row = self.FindValue()
		elif len(self.rows):
			if self.direction > 0:
				self.pos += 1
				if self.pos >= len(self.rows):
					self.pos = 0
			else:
				self.pos -= 1
				if self.pos < 0:
					self.pos = len(self.rows) - 1
			row = self.rows[self.pos]
		else:
			row = -1
		return (True, row)

	def Find(self, value, direction, pattern, context, callback):
		self.value, self.direction, self.pattern, self.last_value, self.last_pattern = (value, direction,pattern, self.value, self.pattern)
		# Use a thread so the UI is not blocked
		thread = Thread(self.FindThread)
		thread.done.connect(lambda row, t=thread, c=callback: self.FindDone(t, c, row), Qt.QueuedConnection)
		thread.start()

	def FindDone(self, thread, callback, row):
		callback(row)

# Number of database records to fetch in one go

glb_chunk_sz = 10000

# Background process for SQL data fetcher

class SQLFetcherProcess():

	def __init__(self, dbref, sql, buffer, head, tail, fetch_count, fetching_done, process_target, wait_event, fetched_event, prep):
		# Need a unique connection name
		conn_name = "SQLFetcher" + str(os.getpid())
		self.db, dbname = dbref.Open(conn_name)
		self.sql = sql
		self.buffer = buffer
		self.head = head
		self.tail = tail
		self.fetch_count = fetch_count
		self.fetching_done = fetching_done
		self.process_target = process_target
		self.wait_event = wait_event
		self.fetched_event = fetched_event
		self.prep = prep
		self.query = QSqlQuery(self.db)
		self.query_limit = 0 if "$$last_id$$" in sql else 2
		self.last_id = -1
		self.fetched = 0
		self.more = True
		self.local_head = self.head.value
		self.local_tail = self.tail.value

	def Select(self):
		if self.query_limit:
			if self.query_limit == 1:
				return
			self.query_limit -= 1
		stmt = self.sql.replace("$$last_id$$", str(self.last_id))
		QueryExec(self.query, stmt)

	def Next(self):
		if not self.query.next():
			self.Select()
			if not self.query.next():
				return None
		self.last_id = self.query.value(0)
		return self.prep(self.query)

	def WaitForTarget(self):
		while True:
			self.wait_event.clear()
			target = self.process_target.value
			if target > self.fetched or target < 0:
				break
			self.wait_event.wait()
		return target

	def HasSpace(self, sz):
		if self.local_tail <= self.local_head:
			space = len(self.buffer) - self.local_head
			if space > sz:
				return True
			if space >= glb_nsz:
				# Use 0 (or space < glb_nsz) to mean there is no more at the top of the buffer
				nd = pickle.dumps(0, pickle.HIGHEST_PROTOCOL)
				self.buffer[self.local_head : self.local_head + len(nd)] = nd
			self.local_head = 0
		if self.local_tail - self.local_head > sz:
			return True
		return False

	def WaitForSpace(self, sz):
		if self.HasSpace(sz):
			return
		while True:
			self.wait_event.clear()
			self.local_tail = self.tail.value
			if self.HasSpace(sz):
				return
			self.wait_event.wait()

	def AddToBuffer(self, obj):
		d = pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
		n = len(d)
		nd = pickle.dumps(n, pickle.HIGHEST_PROTOCOL)
		sz = n + glb_nsz
		self.WaitForSpace(sz)
		pos = self.local_head
		self.buffer[pos : pos + len(nd)] = nd
		self.buffer[pos + glb_nsz : pos + sz] = d
		self.local_head += sz

	def FetchBatch(self, batch_size):
		fetched = 0
		while batch_size > fetched:
			obj = self.Next()
			if obj is None:
				self.more = False
				break
			self.AddToBuffer(obj)
			fetched += 1
		if fetched:
			self.fetched += fetched
			with self.fetch_count.get_lock():
				self.fetch_count.value += fetched
			self.head.value = self.local_head
			self.fetched_event.set()

	def Run(self):
		while self.more:
			target = self.WaitForTarget()
			if target < 0:
				break
			batch_size = min(glb_chunk_sz, target - self.fetched)
			self.FetchBatch(batch_size)
		self.fetching_done.value = True
		self.fetched_event.set()

def SQLFetcherFn(*x):
	process = SQLFetcherProcess(*x)
	process.Run()

# SQL data fetcher

class SQLFetcher(QObject):

	done = Signal(object)

	def __init__(self, glb, sql, prep, process_data, parent=None):
		super(SQLFetcher, self).__init__(parent)
		self.process_data = process_data
		self.more = True
		self.target = 0
		self.last_target = 0
		self.fetched = 0
		self.buffer_size = 16 * 1024 * 1024
		self.buffer = Array(c_char, self.buffer_size, lock=False)
		self.head = Value(c_longlong)
		self.tail = Value(c_longlong)
		self.local_tail = 0
		self.fetch_count = Value(c_longlong)
		self.fetching_done = Value(c_bool)
		self.last_count = 0
		self.process_target = Value(c_longlong)
		self.wait_event = Event()
		self.fetched_event = Event()
		glb.AddInstanceToShutdownOnExit(self)
		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))
		self.process.start()
		self.thread = Thread(self.Thread)
		self.thread.done.connect(self.ProcessData, Qt.QueuedConnection)
		self.thread.start()

	def Shutdown(self):
		# Tell the thread and process to exit
		self.process_target.value = -1
		self.wait_event.set()
		self.more = False
		self.fetching_done.value = True
		self.fetched_event.set()

	def Thread(self):
		if not self.more:
			return True, 0
		while True:
			self.fetched_event.clear()
			fetch_count = self.fetch_count.value
			if fetch_count != self.last_count:
				break
			if self.fetching_done.value:
				self.more = False
				return True, 0
			self.fetched_event.wait()
		count = fetch_count - self.last_count
		self.last_count = fetch_count
		self.fetched += count
		return False, count

	def Fetch(self, nr):
		if not self.more:
			# -1 inidcates there are no more
			return -1
		result = self.fetched
		extra = result + nr - self.target
		if extra > 0:
			self.target += extra
			# process_target < 0 indicates shutting down
			if self.process_target.value >= 0:
				self.process_target.value = self.target
			self.wait_event.set()
		return result

	def RemoveFromBuffer(self):
		pos = self.local_tail
		if len(self.buffer) - pos < glb_nsz:
			pos = 0
		n = pickle.loads(self.buffer[pos : pos + glb_nsz])
		if n == 0:
			pos = 0
			n = pickle.loads(self.buffer[0 : glb_nsz])
		pos += glb_nsz
		obj = pickle.loads(self.buffer[pos : pos + n])
		self.local_tail = pos + n
		return obj

	def ProcessData(self, count):
		for i in xrange(count):
			obj = self.RemoveFromBuffer()
			self.process_data(obj)
		self.tail.value = self.local_tail
		self.wait_event.set()
		self.done.emit(count)

# Fetch more records bar

class FetchMoreRecordsBar():

	def __init__(self, model, parent):
		self.model = model

		self.label = QLabel("Number of records (x " + "{:,}".format(glb_chunk_sz) + ") to fetch:")
		self.label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.fetch_count = QSpinBox()
		self.fetch_count.setRange(1, 1000000)
		self.fetch_count.setValue(10)
		self.fetch_count.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.fetch = QPushButton("Go!")
		self.fetch.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
		self.fetch.released.connect(self.FetchMoreRecords)

		self.progress = QProgressBar()
		self.progress.setRange(0, 100)
		self.progress.hide()

		self.done_label = QLabel("All records fetched")
		self.done_label.hide()

		self.spacer = QLabel("")

		self.close_button = QToolButton()
		self.close_button.setIcon(parent.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
		self.close_button.released.connect(self.Deactivate)

		self.hbox = QHBoxLayout()
		self.hbox.setContentsMargins(0, 0, 0, 0)

		self.hbox.addWidget(self.label)
		self.hbox.addWidget(self.fetch_count)
		self.hbox.addWidget(self.fetch)
		self.hbox.addWidget(self.spacer)
		self.hbox.addWidget(self.progress)
		self.hbox.addWidget(self.done_label)
		self.hbox.addWidget(self.close_button)

		self.bar = QWidget()
		self.bar.setLayout(self.hbox)
		self.bar.show()

		self.in_progress = False
		self.model.progress.connect(self.Progress)

		self.done = False

		if not model.HasMoreRecords():
			self.Done()

	def Widget(self):
		return self.bar

	def Activate(self):
		self.bar.show()
		self.fetch.setFocus()

	def Deactivate(self):
		self.bar.hide()

	def Enable(self, enable):
		self.fetch.setEnabled(enable)
		self.fetch_count.setEnabled(enable)

	def Busy(self):
		self.Enable(False)
		self.fetch.hide()
		self.spacer.hide()
		self.progress.show()

	def Idle(self):
		self.in_progress = False
		self.Enable(True)
		self.progress.hide()
		self.fetch.show()
		self.spacer.show()

	def Target(self):
		return self.fetch_count.value() * glb_chunk_sz

	def Done(self):
		self.done = True
		self.Idle()
		self.label.hide()
		self.fetch_count.hide()
		self.fetch.hide()
		self.spacer.hide()
		self.done_label.show()

	def Progress(self, count):
		if self.in_progress:
			if count:
				percent = ((count - self.start) * 100) / self.Target()
				if percent >= 100:
					self.Idle()
				else:
					self.progress.setValue(percent)
		if not count:
			# Count value of zero means no more records
			self.Done()

	def FetchMoreRecords(self):
		if self.done:
			return
		self.progress.setValue(0)
		self.Busy()
		self.in_progress = True
		self.start = self.model.FetchMoreRecords(self.Target())

# Brance data model level two item

class BranchLevelTwoItem():

	def __init__(self, row, col, text, parent_item):
		self.row = row
		self.parent_item = parent_item
		self.data = [""] * (col + 1)
		self.data[col] = text
		self.level = 2

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def childCount(self):
		return 0

	def hasChildren(self):
		return False

	def getData(self, column):
		return self.data[column]

# Brance data model level one item

class BranchLevelOneItem():

	def __init__(self, glb, row, data, parent_item):
		self.glb = glb
		self.row = row
		self.parent_item = parent_item
		self.child_count = 0
		self.child_items = []
		self.data = data[1:]
		self.dbid = data[0]
		self.level = 1
		self.query_done = False
		self.br_col = len(self.data) - 1

	def getChildItem(self, row):
		return self.child_items[row]

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def Select(self):
		self.query_done = True

		if not self.glb.have_disassembler:
			return

		query = QSqlQuery(self.glb.db)

		QueryExec(query, "SELECT cpu, to_dso_id, to_symbol_id, to_sym_offset, short_name, long_name, build_id, sym_start, to_ip"
				  " FROM samples"
				  " INNER JOIN dsos ON samples.to_dso_id = dsos.id"
				  " INNER JOIN symbols ON samples.to_symbol_id = symbols.id"
				  " WHERE samples.id = " + str(self.dbid))
		if not query.next():
			return
		cpu = query.value(0)
		dso = query.value(1)
		sym = query.value(2)
		if dso == 0 or sym == 0:
			return
		off = query.value(3)
		short_name = query.value(4)
		long_name = query.value(5)
		build_id = query.value(6)
		sym_start = query.value(7)
		ip = query.value(8)

		QueryExec(query, "SELECT samples.dso_id, symbol_id, sym_offset, sym_start"
				  " FROM samples"
				  " INNER JOIN symbols ON samples.symbol_id = symbols.id"
				  " WHERE samples.id > " + str(self.dbid) + " AND cpu = " + str(cpu) +
				  " ORDER BY samples.id"
				  " LIMIT 1")
		if not query.next():
			return
		if query.value(0) != dso:
			# Cannot disassemble from one dso to another
			return
		bsym = query.value(1)
		boff = query.value(2)
		bsym_start = query.value(3)
		if bsym == 0:
			return
		tot = bsym_start + boff + 1 - sym_start - off
		if tot <= 0 or tot > 16384:
			return

		inst = self.glb.disassembler.Instruction()
		f = self.glb.FileFromNamesAndBuildId(short_name, long_name, build_id)
		if not f:
			return
		mode = 0 if Is64Bit(f) else 1
		self.glb.disassembler.SetMode(inst, mode)

		buf_sz = tot + 16
		buf = create_string_buffer(tot + 16)
		f.seek(sym_start + off)
		buf.value = f.read(buf_sz)
		buf_ptr = addressof(buf)
		i = 0
		while tot > 0:
			cnt, text = self.glb.disassembler.DisassembleOne(inst, buf_ptr, buf_sz, ip)
			if cnt:
				byte_str = tohex(ip).rjust(16)
				for k in xrange(cnt):
					byte_str += " %02x" % ord(buf[i])
					i += 1
				while k < 15:
					byte_str += "   "
					k += 1
				self.child_items.append(BranchLevelTwoItem(0, self.br_col, byte_str + " " + text, self))
				self.child_count += 1
			else:
				return
			buf_ptr += cnt
			tot -= cnt
			buf_sz -= cnt
			ip += cnt

	def childCount(self):
		if not self.query_done:
			self.Select()
			if not self.child_count:
				return -1
		return self.child_count

	def hasChildren(self):
		if not self.query_done:
			return True
		return self.child_count > 0

	def getData(self, column):
		return self.data[column]

# Brance data model root item

class BranchRootItem():

	def __init__(self):
		self.child_count = 0
		self.child_items = []
		self.level = 0

	def getChildItem(self, row):
		return self.child_items[row]

	def getParentItem(self):
		return None

	def getRow(self):
		return 0

	def childCount(self):
		return self.child_count

	def hasChildren(self):
		return self.child_count > 0

	def getData(self, column):
		return ""

# Calculate instructions per cycle

def CalcIPC(cyc_cnt, insn_cnt):
	if cyc_cnt and insn_cnt:
		ipc = Decimal(float(insn_cnt) / cyc_cnt)
		ipc = str(ipc.quantize(Decimal(".01"), rounding=ROUND_HALF_UP))
	else:
		ipc = "0"
	return ipc

# Branch data preparation

def BranchDataPrepBr(query, data):
	data.append(tohex(query.value(8)).rjust(16) + " " + query.value(9) + offstr(query.value(10)) +
			" (" + dsoname(query.value(11)) + ")" + " -> " +
			tohex(query.value(12)) + " " + query.value(13) + offstr(query.value(14)) +
			" (" + dsoname(query.value(15)) + ")")

def BranchDataPrepIPC(query, data):
	insn_cnt = query.value(16)
	cyc_cnt = query.value(17)
	ipc = CalcIPC(cyc_cnt, insn_cnt)
	data.append(insn_cnt)
	data.append(cyc_cnt)
	data.append(ipc)

def BranchDataPrep(query):
	data = []
	for i in xrange(0, 8):
		data.append(query.value(i))
	BranchDataPrepBr(query, data)
	return data

def BranchDataPrepWA(query):
	data = []
	data.append(query.value(0))
	# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string
	data.append("{:>19}".format(query.value(1)))
	for i in xrange(2, 8):
		data.append(query.value(i))
	BranchDataPrepBr(query, data)
	return data

def BranchDataWithIPCPrep(query):
	data = []
	for i in xrange(0, 8):
		data.append(query.value(i))
	BranchDataPrepIPC(query, data)
	BranchDataPrepBr(query, data)
	return data

def BranchDataWithIPCPrepWA(query):
	data = []
	data.append(query.value(0))
	# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string
	data.append("{:>19}".format(query.value(1)))
	for i in xrange(2, 8):
		data.append(query.value(i))
	BranchDataPrepIPC(query, data)
	BranchDataPrepBr(query, data)
	return data

# Branch data model

class BranchModel(TreeModel):

	progress = Signal(object)

	def __init__(self, glb, event_id, where_clause, parent=None):
		super(BranchModel, self).__init__(glb, None, parent)
		self.event_id = event_id
		self.more = True
		self.populated = 0
		self.have_ipc = IsSelectable(glb.db, "samples", columns = "insn_count, cyc_count")
		if self.have_ipc:
			select_ipc = ", insn_count, cyc_count"
			prep_fn = BranchDataWithIPCPrep
			prep_wa_fn = BranchDataWithIPCPrepWA
		else:
			select_ipc = ""
			prep_fn = BranchDataPrep
			prep_wa_fn = BranchDataPrepWA
		sql = ("SELECT samples.id, time, cpu, comm, pid, tid, branch_types.name,"
			" CASE WHEN in_tx = '0' THEN 'No' ELSE 'Yes' END,"
			" ip, symbols.name, sym_offset, dsos.short_name,"
			" to_ip, to_symbols.name, to_sym_offset, to_dsos.short_name"
			+ select_ipc +
			" FROM samples"
			" INNER JOIN comms ON comm_id = comms.id"
			" INNER JOIN threads ON thread_id = threads.id"
			" INNER JOIN branch_types ON branch_type = branch_types.id"
			" INNER JOIN symbols ON symbol_id = symbols.id"
			" INNER JOIN symbols to_symbols ON to_symbol_id = to_symbols.id"
			" INNER JOIN dsos ON samples.dso_id = dsos.id"
			" INNER JOIN dsos AS to_dsos ON samples.to_dso_id = to_dsos.id"
			" WHERE samples.id > $$last_id$$" + where_clause +
			" AND evsel_id = " + str(self.event_id) +
			" ORDER BY samples.id"
			" LIMIT " + str(glb_chunk_sz))
		if pyside_version_1 and sys.version_info[0] == 3:
			prep = prep_fn
		else:
			prep = prep_wa_fn
		self.fetcher = SQLFetcher(glb, sql, prep, self.AddSample)
		self.fetcher.done.connect(self.Update)
		self.fetcher.Fetch(glb_chunk_sz)

	def GetRoot(self):
		return BranchRootItem()

	def columnCount(self, parent=None):
		if self.have_ipc:
			return 11
		else:
			return 8

	def columnHeader(self, column):
		if self.have_ipc:
			return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Insn Cnt", "Cyc Cnt", "IPC", "Branch")[column]
		else:
			return ("Time", "CPU", "Command", "PID", "TID", "Branch Type", "In Tx", "Branch")[column]

	def columnFont(self, column):
		if self.have_ipc:
			br_col = 10
		else:
			br_col = 7
		if column != br_col:
			return None
		return QFont("Monospace")

	def DisplayData(self, item, index):
		if item.level == 1:
			self.FetchIfNeeded(item.row)
		return item.getData(index.column())

	def AddSample(self, data):
		child = BranchLevelOneItem(self.glb, self.populated, data, self.root)
		self.root.child_items.append(child)
		self.populated += 1

	def Update(self, fetched):
		if not fetched:
			self.more = False
			self.progress.emit(0)
		child_count = self.root.child_count
		count = self.populated - child_count
		if count > 0:
			parent = QModelIndex()
			self.beginInsertRows(parent, child_count, child_count + count - 1)
			self.insertRows(child_count, count, parent)
			self.root.child_count += count
			self.endInsertRows()
			self.progress.emit(self.root.child_count)

	def FetchMoreRecords(self, count):
		current = self.root.child_count
		if self.more:
			self.fetcher.Fetch(count)
		else:
			self.progress.emit(0)
		return current

	def HasMoreRecords(self):
		return self.more

# Report Variables

class ReportVars():

	def __init__(self, name = "", where_clause = "", limit = ""):
		self.name = name
		self.where_clause = where_clause
		self.limit = limit

	def UniqueId(self):
		return str(self.where_clause + ";" + self.limit)

# Branch window

class BranchWindow(QMdiSubWindow):

	def __init__(self, glb, event_id, report_vars, parent=None):
		super(BranchWindow, self).__init__(parent)

		model_name = "Branch Events " + str(event_id) +  " " + report_vars.UniqueId()

		self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, report_vars.where_clause))

		self.view = QTreeView()
		self.view.setUniformRowHeights(True)
		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
		self.view.CopyCellsToClipboard = CopyTreeCellsToClipboard
		self.view.setModel(self.model)

		self.ResizeColumnsToContents()

		self.context_menu = TreeContextMenu(self.view)

		self.find_bar = FindBar(self, self, True)

		self.finder = ChildDataItemFinder(self.model.root)

		self.fetch_bar = FetchMoreRecordsBar(self.model, self)

		self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name + " Branch Events")

	def ResizeColumnToContents(self, column, n):
		# Using the view's resizeColumnToContents() here is extrememly slow
		# so implement a crude alternative
		mm = "MM" if column else "MMMM"
		font = self.view.font()
		metrics = QFontMetrics(font)
		max = 0
		for row in xrange(n):
			val = self.model.root.child_items[row].data[column]
			len = metrics.width(str(val) + mm)
			max = len if len > max else max
		val = self.model.columnHeader(column)
		len = metrics.width(str(val) + mm)
		max = len if len > max else max
		self.view.setColumnWidth(column, max)

	def ResizeColumnsToContents(self):
		n = min(self.model.root.child_count, 100)
		if n < 1:
			# No data yet, so connect a signal to notify when there is
			self.model.rowsInserted.connect(self.UpdateColumnWidths)
			return
		columns = self.model.columnCount()
		for i in xrange(columns):
			self.ResizeColumnToContents(i, n)

	def UpdateColumnWidths(self, *x):
		# This only needs to be done once, so disconnect the signal now
		self.model.rowsInserted.disconnect(self.UpdateColumnWidths)
		self.ResizeColumnsToContents()

	def Find(self, value, direction, pattern, context):
		self.view.setFocus()
		self.find_bar.Busy()
		self.finder.Find(value, direction, pattern, context, self.FindDone)

	def FindDone(self, row):
		self.find_bar.Idle()
		if row >= 0:
			self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))
		else:
			self.find_bar.NotFound()

# Line edit data item

class LineEditDataItem(object):

	def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
		self.glb = glb
		self.label = label
		self.placeholder_text = placeholder_text
		self.parent = parent
		self.id = id

		self.value = default

		self.widget = QLineEdit(default)
		self.widget.editingFinished.connect(self.Validate)
		self.widget.textChanged.connect(self.Invalidate)
		self.red = False
		self.error = ""
		self.validated = True

		if placeholder_text:
			self.widget.setPlaceholderText(placeholder_text)

	def TurnTextRed(self):
		if not self.red:
			palette = QPalette()
			palette.setColor(QPalette.Text,Qt.red)
			self.widget.setPalette(palette)
			self.red = True

	def TurnTextNormal(self):
		if self.red:
			palette = QPalette()
			self.widget.setPalette(palette)
			self.red = False

	def InvalidValue(self, value):
		self.value = ""
		self.TurnTextRed()
		self.error = self.label + " invalid value '" + value + "'"
		self.parent.ShowMessage(self.error)

	def Invalidate(self):
		self.validated = False

	def DoValidate(self, input_string):
		self.value = input_string.strip()

	def Validate(self):
		self.validated = True
		self.error = ""
		self.TurnTextNormal()
		self.parent.ClearMessage()
		input_string = self.widget.text()
		if not len(input_string.strip()):
			self.value = ""
			return
		self.DoValidate(input_string)

	def IsValid(self):
		if not self.validated:
			self.Validate()
		if len(self.error):
			self.parent.ShowMessage(self.error)
			return False
		return True

	def IsNumber(self, value):
		try:
			x = int(value)
		except:
			x = 0
		return str(x) == value

# Non-negative integer ranges dialog data item

class NonNegativeIntegerRangesDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, column_name, parent):
		super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent)

		self.column_name = column_name

	def DoValidate(self, input_string):
		singles = []
		ranges = []
		for value in [x.strip() for x in input_string.split(",")]:
			if "-" in value:
				vrange = value.split("-")
				if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
					return self.InvalidValue(value)
				ranges.append(vrange)
			else:
				if not self.IsNumber(value):
					return self.InvalidValue(value)
				singles.append(value)
		ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
		if len(singles):
			ranges.append(self.column_name + " IN (" + ",".join(singles) + ")")
		self.value = " OR ".join(ranges)

# Positive integer dialog data item

class PositiveIntegerDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""):
		super(PositiveIntegerDataItem, self).__init__(glb, label, placeholder_text, parent, id, default)

	def DoValidate(self, input_string):
		if not self.IsNumber(input_string.strip()):
			return self.InvalidValue(input_string)
		value = int(input_string.strip())
		if value <= 0:
			return self.InvalidValue(input_string)
		self.value = str(value)

# Dialog data item converted and validated using a SQL table

class SQLTableDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent):
		super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent)

		self.table_name = table_name
		self.match_column = match_column
		self.column_name1 = column_name1
		self.column_name2 = column_name2

	def ValueToIds(self, value):
		ids = []
		query = QSqlQuery(self.glb.db)
		stmt = "SELECT id FROM " + self.table_name + " WHERE " + self.match_column + " = '" + value + "'"
		ret = query.exec_(stmt)
		if ret:
			while query.next():
				ids.append(str(query.value(0)))
		return ids

	def DoValidate(self, input_string):
		all_ids = []
		for value in [x.strip() for x in input_string.split(",")]:
			ids = self.ValueToIds(value)
			if len(ids):
				all_ids.extend(ids)
			else:
				return self.InvalidValue(value)
		self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
		if self.column_name2:
			self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"

# Sample time ranges dialog data item converted and validated using 'samples' SQL table

class SampleTimeRangesDataItem(LineEditDataItem):

	def __init__(self, glb, label, placeholder_text, column_name, parent):
		self.column_name = column_name

		self.last_id = 0
		self.first_time = 0
		self.last_time = 2 ** 64

		query = QSqlQuery(glb.db)
		QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1")
		if query.next():
			self.last_id = int(query.value(0))
		self.first_time = int(glb.HostStartTime())
		self.last_time = int(glb.HostFinishTime())
		if placeholder_text:
			placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)

		super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent)

	def IdBetween(self, query, lower_id, higher_id, order):
		QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1")
		if query.next():
			return True, int(query.value(0))
		else:
			return False, 0

	def BinarySearchTime(self, lower_id, higher_id, target_time, get_floor):
		query = QSqlQuery(self.glb.db)
		while True:
			next_id = int((lower_id + higher_id) / 2)
			QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
			if not query.next():
				ok, dbid = self.IdBetween(query, lower_id, next_id, "DESC")
				if not ok:
					ok, dbid = self.IdBetween(query, next_id, higher_id, "")
					if not ok:
						return str(higher_id)
				next_id = dbid
				QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
			next_time = int(query.value(0))
			if get_floor:
				if target_time > next_time:
					lower_id = next_id
				else:
					higher_id = next_id
				if higher_id <= lower_id + 1:
					return str(higher_id)
			else:
				if target_time >= next_time:
					lower_id = next_id
				else:
					higher_id = next_id
				if higher_id <= lower_id + 1:
					return str(lower_id)

	def ConvertRelativeTime(self, val):
		mult = 1
		suffix = val[-2:]
		if suffix == "ms":
			mult = 1000000
		elif suffix == "us":
			mult = 1000
		elif suffix == "ns":
			mult = 1
		else:
			return val
		val = val[:-2].strip()
		if not self.IsNumber(val):
			return val
		val = int(val) * mult
		if val >= 0:
			val += self.first_time
		else:
			val += self.last_time
		return str(val)

	def ConvertTimeRange(self, vrange):
		if vrange[0] == "":
			vrange[0] = str(self.first_time)
		if vrange[1] == "":
			vrange[1] = str(self.last_time)
		vrange[0] = self.ConvertRelativeTime(vrange[0])
		vrange[1] = self.ConvertRelativeTime(vrange[1])
		if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
			return False
		beg_range = max(int(vrange[0]), self.first_time)
		end_range = min(int(vrange[1]), self.last_time)
		if beg_range > self.last_time or end_range < self.first_time:
			return False
		vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)
		vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False)
		return True

	def AddTimeRange(self, value, ranges):
		n = value.count("-")
		if n == 1:
			pass
		elif n == 2:
			if value.split("-")[1].strip() == "":
				n = 1
		elif n == 3:
			n = 2
		else:
			return False
		pos = findnth(value, "-", n)
		vrange = [value[:pos].strip() ,value[pos+1:].strip()]
		if self.ConvertTimeRange(vrange):
			ranges.append(vrange)
			return True
		return False

	def DoValidate(self, input_string):
		ranges = []
		for value in [x.strip() for x in input_string.split(",")]:
			if not self.AddTimeRange(value, ranges):
				return self.InvalidValue(value)
		ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
		self.value = " OR ".join(ranges)

# Report Dialog Base

class ReportDialogBase(QDialog):

	def __init__(self, glb, title, items, partial, parent=None):
		super(ReportDialogBase, self).__init__(parent)

		self.glb = glb

		self.report_vars = ReportVars()

		self.setWindowTitle(title)
		self.setMinimumWidth(600)

		self.data_items = [x(glb, self) for x in items]

		self.partial = partial

		self.grid = QGridLayout()

		for row in xrange(len(self.data_items)):
			self.grid.addWidget(QLabel(self.data_items[row].label), row, 0)
			self.grid.addWidget(self.data_items[row].widget, row, 1)

		self.status = QLabel()

		self.ok_button = QPushButton("Ok", self)
		self.ok_button.setDefault(True)
		self.ok_button.released.connect(self.Ok)
		self.ok_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.cancel_button = QPushButton("Cancel", self)
		self.cancel_button.released.connect(self.reject)
		self.cancel_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

		self.hbox = QHBoxLayout()
		#self.hbox.addStretch()
		self.hbox.addWidget(self.status)
		self.hbox.addWidget(self.ok_button)
		self.hbox.addWidget(self.cancel_button)

		self.vbox = QVBoxLayout()
		self.vbox.addLayout(self.grid)
		self.vbox.addLayout(self.hbox)

		self.setLayout(self.vbox)

	def Ok(self):
		vars = self.report_vars
		for d in self.data_items:
			if d.id == "REPORTNAME":
				vars.name = d.value
		if not vars.name:
			self.ShowMessage("Report name is required")
			return
		for d in self.data_items:
			if not d.IsValid():
				return
		for d in self.data_items[1:]:
			if d.id == "LIMIT":
				vars.limit = d.value
			elif len(d.value):
				if len(vars.where_clause):
					vars.where_clause += " AND "
				vars.where_clause += d.value
		if len(vars.where_clause):
			if self.partial:
				vars.where_clause = " AND ( " + vars.where_clause + " ) "
			else:
				vars.where_clause = " WHERE " + vars.where_clause + " "
		self.accept()

	def ShowMessage(self, msg):
		self.status.setText("<font color=#FF0000>" + msg)

	def ClearMessage(self):
		self.status.setText("")

# Selected branch report creation dialog

class SelectedBranchDialog(ReportDialogBase):

	def __init__(self, glb, parent=None):
		title = "Selected Branches"
		items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),
			 lambda g, p: SampleTimeRangesDataItem(g, "Time ranges:", "Enter time ranges", "samples.id", p),
			 lambda g, p: NonNegativeIntegerRangesDataItem(g, "CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "cpu", p),
			 lambda g, p: SQLTableDataItem(g, "Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id", p),
			 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id", p),
			 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p))
		super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent)

# Event list

def GetEventList(db):
	events = []
	query = QSqlQuery(db)
	QueryExec(query, "SELECT name FROM selected_events WHERE id > 0 ORDER BY id")
	while query.next():
		events.append(query.value(0))
	return events

# Is a table selectable

def IsSelectable(db, table, sql = "", columns = "*"):
	query = QSqlQuery(db)
	try:
		QueryExec(query, "SELECT " + columns + " FROM " + table + " " + sql + " LIMIT 1")
	except:
		return False
	return True

# SQL table data model item

class SQLTableItem():

	def __init__(self, row, data):
		self.row = row
		self.data = data

	def getData(self, column):
		return self.data[column]

# SQL table data model

class SQLTableModel(TableModel):

	progress = Signal(object)

	def __init__(self, glb, sql, column_headers, parent=None):
		super(SQLTableModel, self).__init__(parent)
		self.glb = glb
		self.more = True
		self.populated = 0
		self.column_headers = column_headers
		self.fetcher = SQLFetcher(glb, sql, lambda x, y=len(column_headers): self.SQLTableDataPrep(x, y), self.AddSample)
		self.fetcher.done.connect(self.Update)
		self.fetcher.Fetch(glb_chunk_sz)

	def DisplayData(self, item, index):
		self.FetchIfNeeded(item.row)
		return item.getData(index.column())

	def AddSample(self, data):
		child = SQLTableItem(self.populated, data)
		self.child_items.append(child)
		self.populated += 1

	def Update(self, fetched):
		if not fetched:
			self.more = False
			self.progress.emit(0)
		child_count = self.child_count
		count = self.populated - child_count
		if count > 0:
			parent = QModelIndex()
			self.beginInsertRows(parent, child_count, child_count + count - 1)
			self.insertRows(child_count, count, parent)
			self.child_count += count
			self.endInsertRows()
			self.progress.emit(self.child_count)

	def FetchMoreRecords(self, count):
		current = self.child_count
		if self.more:
			self.fetcher.Fetch(count)
		else:
			self.progress.emit(0)
		return current

	def HasMoreRecords(self):
		return self.more

	def columnCount(self, parent=None):
		return len(self.column_headers)

	def columnHeader(self, column):
		return self.column_headers[column]

	def SQLTableDataPrep(self, query, count):
		data = []
		for i in xrange(count):
			data.append(query.value(i))
		return data

# SQL automatic table data model

class SQLAutoTableModel(SQLTableModel):

	def __init__(self, glb, table_name, parent=None):
		sql = "SELECT * FROM " + table_name + " WHERE id > $$last_id$$ ORDER BY id LIMIT " + str(glb_chunk_sz)
		if table_name == "comm_threads_view":
			# For now, comm_threads_view has no id column
			sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz)
		column_headers = []
		query = QSqlQuery(glb.db)
		if glb.dbref.is_sqlite3:
			QueryExec(query, "PRAGMA table_info(" + table_name + ")")
			while query.next():
				column_headers.append(query.value(1))
			if table_name == "sqlite_master":
				sql = "SELECT * FROM " + table_name
		else:
			if table_name[:19] == "information_schema.":
				sql = "SELECT * FROM " + table_name
				select_table_name = table_name[19:]
				schema = "information_schema"
			else:
				select_table_name = table_name
				schema = "public"
			QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'")
			while query.next():
				column_headers.append(query.value(0))
		if pyside_version_1 and sys.version_info[0] == 3:
			if table_name == "samples_view":
				self.SQLTableDataPrep = self.samples_view_DataPrep
			if table_name == "samples":
				self.SQLTableDataPrep = self.samples_DataPrep
		super(SQLAutoTableModel, self).__init__(glb, sql, column_headers, parent)

	def samples_view_DataPrep(self, query, count):
		data = []
		data.append(query.value(0))
		# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string
		data.append("{:>19}".format(query.value(1)))
		for i in xrange(2, count):
			data.append(query.value(i))
		return data

	def samples_DataPrep(self, query, count):
		data = []
		for i in xrange(9):
			data.append(query.value(i))
		# Workaround pyside failing to handle large integers (i.e. time) in python3 by converting to a string
		data.append("{:>19}".format(query.value(9)))
		for i in xrange(10, count):
			data.append(query.value(i))
		return data

# Base class for custom ResizeColumnsToContents

class ResizeColumnsToContentsBase(QObject):

	def __init__(self, parent=None):
		super(ResizeColumnsToContentsBase, self).__init__(parent)

	def ResizeColumnToContents(self, column, n):
		# Using the view's resizeColumnToContents() here is extrememly slow
		# so implement a crude alternative
		font = self.view.font()
		metrics = QFontMetrics(font)
		max = 0
		for row in xrange(n):
			val = self.data_model.child_items[row].data[column]
			len = metrics.width(str(val) + "MM")
			max = len if len > max else max
		val = self.data_model.columnHeader(column)
		len = metrics.width(str(val) + "MM")
		max = len if len > max else max
		self.view.setColumnWidth(column, max)

	def ResizeColumnsToContents(self):
		n = min(self.data_model.child_count, 100)
		if n < 1:
			# No data yet, so connect a signal to notify when there is
			self.data_model.rowsInserted.connect(self.UpdateColumnWidths)
			return
		columns = self.data_model.columnCount()
		for i in xrange(columns):
			self.ResizeColumnToContents(i, n)

	def UpdateColumnWidths(self, *x):
		# This only needs to be done once, so disconnect the signal now
		self.data_model.rowsInserted.disconnect(self.UpdateColumnWidths)
		self.ResizeColumnsToContents()

# Convert value to CSV

def ToCSValue(val):
	if '"' in val:
		val = val.replace('"', '""')
	if "," in val or '"' in val:
		val = '"' + val + '"'
	return val

# Key to sort table model indexes by row / column, assuming fewer than 1000 columns

glb_max_cols = 1000

def RowColumnKey(a):
	return a.row() * glb_max_cols + a.column()

# Copy selected table cells to clipboard

def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False):
	indexes = sorted(view.selectedIndexes(), key=RowColumnKey)
	idx_cnt = len(indexes)
	if not idx_cnt:
		return
	if idx_cnt == 1:
		with_hdr=False
	min_row = indexes[0].row()
	max_row = indexes[0].row()
	min_col = indexes[0].column()
	max_col = indexes[0].column()
	for i in indexes:
		min_row = min(min_row, i.row())
		max_row = max(max_row, i.row())
		min_col = min(min_col, i.column())
		max_col = max(max_col, i.column())
	if max_col > glb_max_cols:
		raise RuntimeError("glb_max_cols is too low")
	max_width = [0] * (1 + max_col - min_col)
	for i in indexes:
		c = i.column() - min_col
		max_width[c] = max(max_width[c], len(str(i.data())))
	text = ""
	pad = ""
	sep = ""
	if with_hdr:
		model = indexes[0].model()
		for col in range(min_col, max_col + 1):
			val = model.headerData(col, Qt.Horizontal, Qt.DisplayRole)
			if as_csv:
				text += sep + ToCSValue(val)
				sep = ","
			else:
				c = col - min_col
				max_width[c] = max(max_width[c], len(val))
				width = max_width[c]
				align = model.headerData(col, Qt.Horizontal, Qt.TextAlignmentRole)
				if align & Qt.AlignRight:
					val = val.rjust(width)
				text += pad + sep + val
				pad = " " * (width - len(val))
				sep = "  "
		text += "\n"
		pad = ""
		sep = ""
	last_row = min_row
	for i in indexes:
		if i.row() > last_row:
			last_row = i.row()
			text += "\n"
			pad = ""
			sep = ""
		if as_csv:
			text += sep + ToCSValue(str(i.data()))
			sep = ","
		else:
			width = max_width[i.column() - min_col]
			if i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
				val = str(i.data()).rjust(width)
			else:
				val = str(i.data())
			text += pad + sep + val
			pad = " " * (width - len(val))
			sep = "  "
	QApplication.clipboard().setText(text)

def CopyTreeCellsToClipboard(view, as_csv=False, with_hdr=False):
	indexes = view.selectedIndexes()
	if not len(indexes):
		return

	selection = view.selectionModel()

	first = None
	for i in indexes:
		above = view.indexAbove(i)
		if not selection.isSelected(above):
			first = i
			break

	if first is None:
		raise RuntimeError("CopyTreeCellsToClipboard internal error")

	model = first.model()
	row_cnt = 0
	col_cnt = model.columnCount(first)
	max_width = [0] * col_cnt

	indent_sz = 2
	indent_str = " " * indent_sz

	expanded_mark_sz = 2
	if sys.version_info[0] == 3:
		expanded_mark = "\u25BC "
		not_expanded_mark = "\u25B6 "
	else:
		expanded_mark = unicode(chr(0xE2) + chr(0x96) + chr(0xBC) + " ", "utf-8")
		not_expanded_mark =  unicode(chr(0xE2) + chr(0x96) + chr(0xB6) + " ", "utf-8")
	leaf_mark = "  "

	if not as_csv:
		pos = first
		while True:
			row_cnt += 1
			row = pos.row()
			for c in range(col_cnt):
				i = pos.sibling(row, c)
				if c:
					n = len(str(i.data()))
				else:
					n = len(str(i.data()).strip())
					n += (i.internalPointer().level - 1) * indent_sz
					n += expanded_mark_sz
				max_width[c] = max(max_width[c], n)
			pos = view.indexBelow(pos)
			if not selection.isSelected(pos):
				break

	text = ""
	pad = ""
	sep = ""
	if with_hdr:
		for c in range(col_cnt):
			val = model.headerData(c, Qt.Horizontal, Qt.DisplayRole).strip()
			if as_csv:
				text += sep + ToCSValue(val)
				sep = ","
			else:
				max_width[c] = max(max_width[c], len(val))
				width = max_width[c]
				align = model.headerData(c, Qt.Horizontal, Qt.TextAlignmentRole)
				if align & Qt.AlignRight:
					val = val.rjust(width)
				text += pad + sep + val
				pad = " " * (width - len(val))
				sep = "   "
		text += "\n"
		pad = ""
		sep = ""

	pos = first
	while True:
		row = pos.row()
		for c in range(col_cnt):
			i = pos.sibling(row, c)
			val = str(i.data())
			if not c:
				if model.hasChildren(i):
					if view.isExpanded(i):
						mark = expanded_mark
					else:
						mark = not_expanded_mark
				else:
					mark = leaf_mark
				val = indent_str * (i.internalPointer().level - 1) + mark + val.strip()
			if as_csv:
				text += sep + ToCSValue(val)
				sep = ","
			else:
				width = max_width[c]
				if c and i.data(Qt.TextAlignmentRole) & Qt.AlignRight:
					val = val.rjust(width)
				text += pad + sep + val
				pad = " " * (width - len(val))
				sep = "   "
		pos = view.indexBelow(pos)
		if not selection.isSelected(pos):
			break
		text = text.rstrip() + "\n"
		pad = ""
		sep = ""

	QApplication.clipboard().setText(text)

def CopyCellsToClipboard(view, as_csv=False, with_hdr=False):
	view.CopyCellsToClipboard(view, as_csv, with_hdr)

def CopyCellsToClipboardHdr(view):
	CopyCellsToClipboard(view, False, True)

def CopyCellsToClipboardCSV(view):
	CopyCellsToClipboard(view, True, True)

# Context menu

class ContextMenu(object):

	def __init__(self, view):
		self.view = view
		self.view.setContextMenuPolicy(Qt.CustomContextMenu)
		self.view.customContextMenuRequested.connect(self.ShowContextMenu)

	def ShowContextMenu(self, pos):
		menu = QMenu(self.view)
		self.AddActions(menu)
		menu.exec_(self.view.mapToGlobal(pos))

	def AddCopy(self, menu):
		menu.addAction(CreateAction("&Copy selection", "Copy to clipboard", lambda: CopyCellsToClipboardHdr(self.view), self.view))
		menu.addAction(CreateAction("Copy selection as CS&V", "Copy to clipboard as CSV", lambda: CopyCellsToClipboardCSV(self.view), self.view))

	def AddActions(self, menu):
		self.AddCopy(menu)

class TreeContextMenu(ContextMenu):

	def __init__(self, view):
		super(TreeContextMenu, self).__init__(view)

	def AddActions(self, menu):
		i = self.view.currentIndex()
		text = str(i.data()).strip()
		if len(text):
			menu.addAction(CreateAction('Copy "' + text + '"', "Copy to clipboard", lambda: QApplication.clipboard().setText(text), self.view))
		self.AddCopy(menu)

# Table window

class TableWindow(QMdiSubWindow, ResizeColumnsToContentsBase):

	def __init__(self, glb, table_name, parent=None):
		super(TableWindow, self).__init__(parent)

		self.data_model = LookupCreateModel(table_name + " Table", lambda: SQLAutoTableModel(glb, table_name))

		self.model = QSortFilterProxyModel()
		self.model.setSourceModel(self.data_model)

		self.view = QTableView()
		self.view.setModel(self.model)
		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.view.verticalHeader().setVisible(False)
		self.view.sortByColumn(-1, Qt.AscendingOrder)
		self.view.setSortingEnabled(True)
		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
		self.view.CopyCellsToClipboard = CopyTableCellsToClipboard

		self.ResizeColumnsToContents()

		self.context_menu = ContextMenu(self.view)

		self.find_bar = FindBar(self, self, True)

		self.finder = ChildDataItemFinder(self.data_model)

		self.fetch_bar = FetchMoreRecordsBar(self.data_model, self)

		self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, table_name + " Table")

	def Find(self, value, direction, pattern, context):
		self.view.setFocus()
		self.find_bar.Busy()
		self.finder.Find(value, direction, pattern, context, self.FindDone)

	def FindDone(self, row):
		self.find_bar.Idle()
		if row >= 0:
			self.view.setCurrentIndex(self.model.mapFromSource(self.data_model.index(row, 0, QModelIndex())))
		else:
			self.find_bar.NotFound()

# Table list

def GetTableList(glb):
	tables = []
	query = QSqlQuery(glb.db)
	if glb.dbref.is_sqlite3:
		QueryExec(query, "SELECT name FROM sqlite_master WHERE type IN ( 'table' , 'view' ) ORDER BY name")
	else:
		QueryExec(query, "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type IN ( 'BASE TABLE' , 'VIEW' ) ORDER BY table_name")
	while query.next():
		tables.append(query.value(0))
	if glb.dbref.is_sqlite3:
		tables.append("sqlite_master")
	else:
		tables.append("information_schema.tables")
		tables.append("information_schema.views")
		tables.append("information_schema.columns")
	return tables

# Top Calls data model

class TopCallsModel(SQLTableModel):

	def __init__(self, glb, report_vars, parent=None):
		text = ""
		if not glb.dbref.is_sqlite3:
			text = "::text"
		limit = ""
		if len(report_vars.limit):
			limit = " LIMIT " + report_vars.limit
		sql = ("SELECT comm, pid, tid, name,"
			" CASE"
			" WHEN (short_name = '[kernel.kallsyms]') THEN '[kernel]'" + text +
			" ELSE short_name"
			" END AS dso,"
			" call_time, return_time, (return_time - call_time) AS elapsed_time, branch_count, "
			" CASE"
			" WHEN (calls.flags = 1) THEN 'no call'" + text +
			" WHEN (calls.flags = 2) THEN 'no return'" + text +
			" WHEN (calls.flags = 3) THEN 'no call/return'" + text +
			" ELSE ''" + text +
			" END AS flags"
			" FROM calls"
			" INNER JOIN call_paths ON calls.call_path_id = call_paths.id"
			" INNER JOIN symbols ON call_paths.symbol_id = symbols.id"
			" INNER JOIN dsos ON symbols.dso_id = dsos.id"
			" INNER JOIN comms ON calls.comm_id = comms.id"
			" INNER JOIN threads ON calls.thread_id = threads.id" +
			report_vars.where_clause +
			" ORDER BY elapsed_time DESC" +
			limit
			)
		column_headers = ("Command", "PID", "TID", "Symbol", "Object", "Call Time", "Return Time", "Elapsed Time (ns)", "Branch Count", "Flags")
		self.alignment = (Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignLeft)
		super(TopCallsModel, self).__init__(glb, sql, column_headers, parent)

	def columnAlignment(self, column):
		return self.alignment[column]

# Top Calls report creation dialog

class TopCallsDialog(ReportDialogBase):

	def __init__(self, glb, parent=None):
		title = "Top Calls by Elapsed Time"
		items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),
			 lambda g, p: SQLTableDataItem(g, "Commands:", "Only calls with these commands will be included", "comms", "comm", "comm_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only calls with these process IDs will be included", "threads", "pid", "thread_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only calls with these thread IDs will be included", "threads", "tid", "thread_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only calls with these DSOs will be included", "dsos", "short_name", "dso_id", "", p),
			 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only calls with these symbols will be included", "symbols", "name", "symbol_id", "", p),
			 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p),
			 lambda g, p: PositiveIntegerDataItem(g, "Record limit:", "Limit selection to this number of records", p, "LIMIT", "100"))
		super(TopCallsDialog, self).__init__(glb, title, items, False, parent)

# Top Calls window

class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase):

	def __init__(self, glb, report_vars, parent=None):
		super(TopCallsWindow, self).__init__(parent)

		self.data_model = LookupCreateModel("Top Calls " + report_vars.UniqueId(), lambda: TopCallsModel(glb, report_vars))
		self.model = self.data_model

		self.view = QTableView()
		self.view.setModel(self.model)
		self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.view.verticalHeader().setVisible(False)
		self.view.setSelectionMode(QAbstractItemView.ContiguousSelection)
		self.view.CopyCellsToClipboard = CopyTableCellsToClipboard

		self.context_menu = ContextMenu(self.view)

		self.ResizeColumnsToContents()

		self.find_bar = FindBar(self, self, True)

		self.finder = ChildDataItemFinder(self.model)

		self.fetch_bar = FetchMoreRecordsBar(self.data_model, self)

		self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget())

		self.setWidget(self.vbox.Widget())

		AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name)

	def Find(self, value, direction, pattern, context):
		self.view.setFocus()
		self.find_bar.Busy()
		self.finder.Find(value, direction, pattern, context, self.FindDone)

	def FindDone(self, row):
		self.find_bar.Idle()
		if row >= 0:
			self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex()))
		else:
			self.find_bar.NotFound()

# Action Definition

def CreateAction(label, tip, callback, parent=None, shortcut=None):
	action = QAction(label, parent)
	if shortcut != None:
		action.setShortcuts(shortcut)
	action.setStatusTip(tip)
	action.triggered.connect(callback)
	return action

# Typical application actions

def CreateExitAction(app, parent=None):
	return CreateAction("&Quit", "Exit the application", app.closeAllWindows, parent, QKeySequence.Quit)

# Typical MDI actions

def CreateCloseActiveWindowAction(mdi_area):
	return CreateAction("Cl&ose", "Close the active window", mdi_area.closeActiveSubWindow, mdi_area)

def CreateCloseAllWindowsAction(mdi_area):
	return CreateAction("Close &All", "Close all the windows", mdi_area.closeAllSubWindows, mdi_area)

def CreateTileWindowsAction(mdi_area):
	return CreateAction("&Tile", "Tile the windows", mdi_area.tileSubWindows, mdi_area)

def CreateCascadeWindowsAction(mdi_area):
	return CreateAction("&Cascade", "Cascade the windows", mdi_area.cascadeSubWindows, mdi_area)

def CreateNextWindowAction(mdi_area):
	return CreateAction("Ne&xt", "Move the focus to the next window", mdi_area.activateNextSubWindow, mdi_area, QKeySequence.NextChild)

def CreatePreviousWindowAction(mdi_area):
	return CreateAction("Pre&vious", "Move the focus to the previous window", mdi_area.activatePreviousSubWindow, mdi_area, QKeySequence.PreviousChild)

# Typical MDI window menu

class WindowMenu():

	def __init__(self, mdi_area, menu):
		self.mdi_area = mdi_area
		self.window_menu = menu.addMenu("&Windows")
		self.close_active_window = CreateCloseActiveWindowAction(mdi_area)
		self.close_all_windows = CreateCloseAllWindowsAction(mdi_area)
		self.tile_windows = CreateTileWindowsAction(mdi_area)
		self.cascade_windows = CreateCascadeWindowsAction(mdi_area)
		self.next_window = CreateNextWindowAction(mdi_area)
		self.previous_window = CreatePreviousWindowAction(mdi_area)
		self.window_menu.aboutToShow.connect(self.Update)

	def Update(self):
		self.window_menu.clear()
		sub_window_count = len(self.mdi_area.subWindowList())
		have_sub_windows = sub_window_count != 0
		self.close_active_window.setEnabled(have_sub_windows)
		self.close_all_windows.setEnabled(have_sub_windows)
		self.tile_windows.setEnabled(have_sub_windows)
		self.cascade_windows.setEnabled(have_sub_windows)
		self.next_window.setEnabled(have_sub_windows)
		self.previous_window.setEnabled(have_sub_windows)
		self.window_menu.addAction(self.close_active_window)
		self.window_menu.addAction(self.close_all_windows)
		self.window_menu.addSeparator()
		self.window_menu.addAction(self.tile_windows)
		self.window_menu.addAction(self.cascade_windows)
		self.window_menu.addSeparator()
		self.window_menu.addAction(self.next_window)
		self.window_menu.addAction(self.previous_window)
		if sub_window_count == 0:
			return
		self.window_menu.addSeparator()
		nr = 1
		for sub_window in self.mdi_area.subWindowList():
			label = str(nr) + " " + sub_window.name
			if nr < 10:
				label = "&" + label
			action = self.window_menu.addAction(label)
			action.setCheckable(True)
			action.setChecked(sub_window == self.mdi_area.activeSubWindow())
			action.triggered.connect(lambda a=None,x=nr: self.setActiveSubWindow(x))
			self.window_menu.addAction(action)
			nr += 1

	def setActiveSubWindow(self, nr):
		self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1])

# Help text

glb_help_text = """
<h1>Contents</h1>
<style>
p.c1 {
    text-indent: 40px;
}
p.c2 {
    text-indent: 80px;
}
}
</style>
<p class=c1><a href=#reports>1. Reports</a></p>
<p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p>
<p class=c2><a href=#calltree>1.2 Call Tree</a></p>
<p class=c2><a href=#allbranches>1.3 All branches</a></p>
<p class=c2><a href=#selectedbranches>1.4 Selected branches</a></p>
<p class=c2><a href=#topcallsbyelapsedtime>1.5 Top calls by elapsed time</a></p>
<p class=c1><a href=#charts>2. Charts</a></p>
<p class=c2><a href=#timechartbycpu>2.1 Time chart by CPU</a></p>
<p class=c1><a href=#tables>3. Tables</a></p>
<h1 id=reports>1. Reports</h1>
<h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2>
The result is a GUI window with a tree representing a context-sensitive
call-graph. Expanding a couple of levels of the tree and adjusting column
widths to suit will display something like:
<pre>
                                         Call Graph: pt_example
Call Path                          Object      Count   Time(ns)  Time(%)  Branch Count   Branch Count(%)
v- ls
    v- 2638:2638
        v- _start                  ld-2.19.so    1     10074071   100.0         211135            100.0
          |- unknown               unknown       1        13198     0.1              1              0.0
          >- _dl_start             ld-2.19.so    1      1400980    13.9          19637              9.3
          >- _d_linit_internal     ld-2.19.so    1       448152     4.4          11094              5.3
          v-__libc_start_main@plt  ls            1      8211741    81.5         180397             85.4
             >- _dl_fixup          ld-2.19.so    1         7607     0.1            108              0.1
             >- __cxa_atexit       libc-2.19.so  1        11737     0.1             10              0.0
             >- __libc_csu_init    ls            1        10354     0.1             10              0.0
             |- _setjmp            libc-2.19.so  1            0     0.0              4              0.0
             v- main               ls            1      8182043    99.6         180254             99.9
</pre>
<h3>Points to note:</h3>
<ul>
<li>The top level is a command name (comm)</li>
<li>The next level is a thread (pid:tid)</li>
<li>Subsequent levels are functions</li>
<li>'Count' is the number of calls</li>
<li>'Time' is the elapsed time until the function returns</li>
<li>Percentages are relative to the level above</li>
<li>'Branch Count' is the total number of branches for that function and all functions that it calls
</ul>
<h3>Find</h3>
Ctrl-F displays a Find bar which finds function names by either an exact match or a pattern match.
The pattern matching symbols are ? for any character and * for zero or more characters.
<h2 id=calltree>1.2 Call Tree</h2>
The Call Tree report is very similar to the Context-Sensitive Call Graph, but the data is not aggregated.
Also the 'Count' column, which would be always 1, is replaced by the 'Call Time'.
<h2 id=allbranches>1.3 All branches</h2>
The All branches report displays all branches in chronological order.
Not all data is fetched immediately. More records can be fetched using the Fetch bar provided.
<h3>Disassembly</h3>
Open a branch to display disassembly. This only works if:
<ol>
<li>The disassembler is available. Currently, only Intel XED is supported - see <a href=#xed>Intel XED Setup</a></li>
<li>The object code is available. Currently, only the perf build ID cache is searched for object code.
The default directory ~/.debug can be overridden by setting environment variable PERF_BUILDID_DIR.
One exception is kcore where the DSO long name is used (refer dsos_view on the Tables menu),
or alternatively, set environment variable PERF_KCORE to the kcore file name.</li>
</ol>
<h4 id=xed>Intel XED Setup</h4>
To use Intel XED, libxed.so must be present.  To build and install libxed.so:
<pre>
git clone https://github.com/intelxed/mbuild.git mbuild
git clone https://github.com/intelxed/xed
cd xed
./mfile.py --share
sudo ./mfile.py --prefix=/usr/local install
sudo ldconfig
</pre>
<h3>Instructions per Cycle (IPC)</h3>
If available, IPC information is displayed in columns 'insn_cnt', 'cyc_cnt' and 'IPC'.
<p><b>Intel PT note:</b> The information applies to the blocks of code ending with, and including, that branch.
Due to the granularity of timing information, the number of cycles for some code blocks will not be known.
In that case, 'insn_cnt', 'cyc_cnt' and 'IPC' are zero, but when 'IPC' is displayed it covers the period
since the previous displayed 'IPC'.
<h3>Find</h3>
Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
Refer to Python documentation for the regular expression syntax.
All columns are searched, but only currently fetched rows are searched.
<h2 id=selectedbranches>1.4 Selected branches</h2>
This is the same as the <a href=#allbranches>All branches</a> report but with the data reduced
by various selection criteria. A dialog box displays available criteria which are AND'ed together.
<h3>1.4.1 Time ranges</h3>
The time ranges hint text shows the total time range. Relative time ranges can also be entered in
ms, us or ns. Also, negative values are relative to the end of trace.  Examples:
<pre>
	81073085947329-81073085958238	From 81073085947329 to 81073085958238
	100us-200us		From 100us to 200us
	10ms-			From 10ms to the end
	-100ns			The first 100ns
	-10ms-			The last 10ms
</pre>
N.B. Due to the granularity of timestamps, there could be no branches in any given time range.
<h2 id=topcallsbyelapsedtime>1.5 Top calls by elapsed time</h2>
The Top calls by elapsed time report displays calls in descending order of time elapsed between when the function was called and when it returned.
The data is reduced by various selection criteria. A dialog box displays available criteria which are AND'ed together.
If not all data is fetched, a Fetch bar is provided. Ctrl-F displays a Find bar.
<h1 id=charts>2. Charts</h1>
<h2 id=timechartbycpu>2.1 Time chart by CPU</h2>
This chart displays context switch information when that data is available. Refer to context_switches_view on the Tables menu.
<h3>Features</h3>
<ol>
<li>Mouse over to highight the task and show the time</li>
<li>Drag the mouse to select a region and zoom by pushing the Zoom button</li>
<li>Go back and forward by pressing the arrow buttons</li>
<li>If call information is available, right-click to show a call tree opened to that task and time.
Note, the call tree may take some time to appear, and there may not be call information for the task or time selected.
</li>
</ol>
<h3>Important</h3>
The graph can be misleading in the following respects:
<ol>
<li>The graph shows the first task on each CPU as running from the beginning of the time range.
Because tracing might start on different CPUs at different times, that is not necessarily the case.
Refer to context_switches_view on the Tables menu to understand what data the graph is based upon.</li>
<li>Similarly, the last task on each CPU can be showing running longer than it really was.
Again, refer to context_switches_view on the Tables menu to understand what data the graph is based upon.</li>
<li>When the mouse is over a task, the highlighted task might not be visible on the legend without scrolling if the legend does not fit fully in the window</li>
</ol>
<h1 id=tables>3. Tables</h1>
The Tables menu shows all tables and views in the database. Most tables have an associated view
which displays the information in a more friendly way. Not all data for large tables is fetched
immediately. More records can be fetched using the Fetch bar provided. Columns can be sorted,
but that can be slow for large tables.
<p>There are also tables of database meta-information.
For SQLite3 databases, the sqlite_master table is included.
For PostgreSQL databases, information_schema.tables/views/columns are included.
<h3>Find</h3>
Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match.
Refer to Python documentation for the regular expression syntax.
All columns are searched, but only currently fetched rows are searched.
<p>N.B. Results are found in id order, so if the table is re-ordered, find-next and find-previous
will go to the next/previous result in id order, instead of display order.
"""

# Help window

class HelpWindow(QMdiSubWindow):

	def __init__(self, glb, parent=None):
		super(HelpWindow, self).__init__(parent)

		self.text = QTextBrowser()
		self.text.setHtml(glb_help_text)
		self.text.setReadOnly(True)
		self.text.setOpenExternalLinks(True)

		self.setWidget(self.text)

		AddSubWindow(glb.mainwindow.mdi_area, self, "Exported SQL Viewer Help")

# Main window that only displays the help text

class HelpOnlyWindow(QMainWindow):

	def __init__(self, parent=None):
		super(HelpOnlyWindow, self).__init__(parent)

		self.setMinimumSize(200, 100)
		self.resize(800, 600)
		self.setWindowTitle("Exported SQL Viewer Help")
		self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))

		self.text = QTextBrowser()
		self.text.setHtml(glb_help_text)
		self.text.setReadOnly(True)
		self.text.setOpenExternalLinks(True)

		self.setCentralWidget(self.text)

# PostqreSQL server version

def PostqreSQLServerVersion(db):
	query = QSqlQuery(db)
	QueryExec(query, "SELECT VERSION()")
	if query.next():
		v_str = query.value(0)
		v_list = v_str.strip().split(" ")
		if v_list[0] == "PostgreSQL" and v_list[2] == "on":
			return v_list[1]
		return v_str
	return "Unknown"

# SQLite version

def SQLiteVersion(db):
	query = QSqlQuery(db)
	QueryExec(query, "SELECT sqlite_version()")
	if query.next():
		return query.value(0)
	return "Unknown"

# About dialog

class AboutDialog(QDialog):

	def __init__(self, glb, parent=None):
		super(AboutDialog, self).__init__(parent)

		self.setWindowTitle("About Exported SQL Viewer")
		self.setMinimumWidth(300)

		pyside_version = "1" if pyside_version_1 else "2"

		text = "<pre>"
		text += "Python version:     " + sys.version.split(" ")[0] + "\n"
		text += "PySide version:     " + pyside_version + "\n"
		text += "Qt version:         " + qVersion() + "\n"
		if glb.dbref.is_sqlite3:
			text += "SQLite version:     " + SQLiteVersion(glb.db) + "\n"
		else:
			text += "PostqreSQL version: " + PostqreSQLServerVersion(glb.db) + "\n"
		text += "</pre>"

		self.text = QTextBrowser()
		self.text.setHtml(text)
		self.text.setReadOnly(True)
		self.text.setOpenExternalLinks(True)

		self.vbox = QVBoxLayout()
		self.vbox.addWidget(self.text)

		self.setLayout(self.vbox)

# Font resize

def ResizeFont(widget, diff):
	font = widget.font()
	sz = font.pointSize()
	font.setPointSize(sz + diff)
	widget.setFont(font)

def ShrinkFont(widget):
	ResizeFont(widget, -1)

def EnlargeFont(widget):
	ResizeFont(widget, 1)

# Unique name for sub-windows

def NumberedWindowName(name, nr):
	if nr > 1:
		name += " <" + str(nr) + ">"
	return name

def UniqueSubWindowName(mdi_area, name):
	nr = 1
	while True:
		unique_name = NumberedWindowName(name, nr)
		ok = True
		for sub_window in mdi_area.subWindowList():
			if sub_window.name == unique_name:
				ok = False
				break
		if ok:
			return unique_name
		nr += 1

# Add a sub-window

def AddSubWindow(mdi_area, sub_window, name):
	unique_name = UniqueSubWindowName(mdi_area, name)
	sub_window.setMinimumSize(200, 100)
	sub_window.resize(800, 600)
	sub_window.setWindowTitle(unique_name)
	sub_window.setAttribute(Qt.WA_DeleteOnClose)
	sub_window.setWindowIcon(sub_window.style().standardIcon(QStyle.SP_FileIcon))
	sub_window.name = unique_name
	mdi_area.addSubWindow(sub_window)
	sub_window.show()

# Main window

class MainWindow(QMainWindow):

	def __init__(self, glb, parent=None):
		super(MainWindow, self).__init__(parent)

		self.glb = glb

		self.setWindowTitle("Exported SQL Viewer: " + glb.dbname)
		self.setWindowIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
		self.setMinimumSize(200, 100)

		self.mdi_area = QMdiArea()
		self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
		self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

		self.setCentralWidget(self.mdi_area)

		menu = self.menuBar()

		file_menu = menu.addMenu("&File")
		file_menu.addAction(CreateExitAction(glb.app, self))

		edit_menu = menu.addMenu("&Edit")
		edit_menu.addAction(CreateAction("&Copy", "Copy to clipboard", self.CopyToClipboard, self, QKeySequence.Copy))
		edit_menu.addAction(CreateAction("Copy as CS&V", "Copy to clipboard as CSV", self.CopyToClipboardCSV, self))
		edit_menu.addAction(CreateAction("&Find...", "Find items", self.Find, self, QKeySequence.Find))
		edit_menu.addAction(CreateAction("Fetch &more records...", "Fetch more records", self.FetchMoreRecords, self, [QKeySequence(Qt.Key_F8)]))
		edit_menu.addAction(CreateAction("&Shrink Font", "Make text smaller", self.ShrinkFont, self, [QKeySequence("Ctrl+-")]))
		edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")]))

		reports_menu = menu.addMenu("&Reports")
		if IsSelectable(glb.db, "calls"):
			reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self))

		if IsSelectable(glb.db, "calls", "WHERE parent_id >= 0"):
			reports_menu.addAction(CreateAction("Call &Tree", "Create a new window containing a call tree", self.NewCallTree, self))

		self.EventMenu(GetEventList(glb.db), reports_menu)

		if IsSelectable(glb.db, "calls"):
			reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self))

		if IsSelectable(glb.db, "context_switches"):
			charts_menu = menu.addMenu("&Charts")
			charts_menu.addAction(CreateAction("&Time chart by CPU", "Create a new window displaying time charts by CPU", self.TimeChartByCPU, self))

		self.TableMenu(GetTableList(glb), menu)

		self.window_menu = WindowMenu(self.mdi_area, menu)

		help_menu = menu.addMenu("&Help")
		help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents))
		help_menu.addAction(CreateAction("&About Exported SQL Viewer", "About this application", self.About, self))

	def Try(self, fn):
		win = self.mdi_area.activeSubWindow()
		if win:
			try:
				fn(win.view)
			except:
				pass

	def CopyToClipboard(self):
		self.Try(CopyCellsToClipboardHdr)

	def CopyToClipboardCSV(self):
		self.Try(CopyCellsToClipboardCSV)

	def Find(self):
		win = self.mdi_area.activeSubWindow()
		if win:
			try:
				win.find_bar.Activate()
			except:
				pass

	def FetchMoreRecords(self):
		win = self.mdi_area.activeSubWindow()
		if win:
			try:
				win.fetch_bar.Activate()
			except:
				pass

	def ShrinkFont(self):
		self.Try(ShrinkFont)

	def EnlargeFont(self):
		self.Try(EnlargeFont)

	def EventMenu(self, events, reports_menu):
		branches_events = 0
		for event in events:
			event = event.split(":")[0]
			if event == "branches":
				branches_events += 1
		dbid = 0
		for event in events:
			dbid += 1
			event = event.split(":")[0]
			if event == "branches":
				label = "All branches" if branches_events == 1 else "All branches " + "(id=" + dbid + ")"
				reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewBranchView(x), self))
				label = "Selected branches" if branches_events == 1 else "Selected branches " + "(id=" + dbid + ")"
				reports_menu.addAction(CreateAction(label, "Create a new window displaying branch events", lambda a=None,x=dbid: self.NewSelectedBranchView(x), self))

	def TimeChartByCPU(self):
		TimeChartByCPUWindow(self.glb, self)

	def TableMenu(self, tables, menu):
		table_menu = menu.addMenu("&Tables")
		for table in tables:
			table_menu.addAction(CreateAction(table, "Create a new window containing a table view", lambda a=None,t=table: self.NewTableView(t), self))

	def NewCallGraph(self):
		CallGraphWindow(self.glb, self)

	def NewCallTree(self):
		CallTreeWindow(self.glb, self)

	def NewTopCalls(self):
		dialog = TopCallsDialog(self.glb, self)
		ret = dialog.exec_()
		if ret:
			TopCallsWindow(self.glb, dialog.report_vars, self)

	def NewBranchView(self, event_id):
		BranchWindow(self.glb, event_id, ReportVars(), self)

	def NewSelectedBranchView(self, event_id):
		dialog = SelectedBranchDialog(self.glb, self)
		ret = dialog.exec_()
		if ret:
			BranchWindow(self.glb, event_id, dialog.report_vars, self)

	def NewTableView(self, table_name):
		TableWindow(self.glb, table_name, self)

	def Help(self):
		HelpWindow(self.glb, self)

	def About(self):
		dialog = AboutDialog(self.glb, self)
		dialog.exec_()

def TryOpen(file_name):
	try:
		return open(file_name, "rb")
	except:
		return None

def Is64Bit(f):
	result = sizeof(c_void_p)
	# ELF support only
	pos = f.tell()
	f.seek(0)
	header = f.read(7)
	f.seek(pos)
	magic = header[0:4]
	if sys.version_info[0] == 2:
		eclass = ord(header[4])
		encoding = ord(header[5])
		version = ord(header[6])
	else:
		eclass = header[4]
		encoding = header[5]
		version = header[6]
	if magic == chr(127) + "ELF" and eclass > 0 and eclass < 3 and encoding > 0 and encoding < 3 and version == 1:
		result = True if eclass == 2 else False
	return result

# Global data

class Glb():

	def __init__(self, dbref, db, dbname):
		self.dbref = dbref
		self.db = db
		self.dbname = dbname
		self.home_dir = os.path.expanduser("~")
		self.buildid_dir = os.getenv("PERF_BUILDID_DIR")
		if self.buildid_dir:
			self.buildid_dir += "/.build-id/"
		else:
			self.buildid_dir = self.home_dir + "/.debug/.build-id/"
		self.app = None
		self.mainwindow = None
		self.instances_to_shutdown_on_exit = weakref.WeakSet()
		try:
			self.disassembler = LibXED()
			self.have_disassembler = True
		except:
			self.have_disassembler = False
		self.host_machine_id = 0
		self.host_start_time = 0
		self.host_finish_time = 0

	def FileFromBuildId(self, build_id):
		file_name = self.buildid_dir + build_id[0:2] + "/" + build_id[2:] + "/elf"
		return TryOpen(file_name)

	def FileFromNamesAndBuildId(self, short_name, long_name, build_id):
		# Assume current machine i.e. no support for virtualization
		if short_name[0:7] == "[kernel" and os.path.basename(long_name) == "kcore":
			file_name = os.getenv("PERF_KCORE")
			f = TryOpen(file_name) if file_name else None
			if f:
				return f
			# For now, no special handling if long_name is /proc/kcore
			f = TryOpen(long_name)
			if f:
				return f
		f = self.FileFromBuildId(build_id)
		if f:
			return f
		return None

	def AddInstanceToShutdownOnExit(self, instance):
		self.instances_to_shutdown_on_exit.add(instance)

	# Shutdown any background processes or threads
	def ShutdownInstances(self):
		for x in self.instances_to_shutdown_on_exit:
			try:
				x.Shutdown()
			except:
				pass

	def GetHostMachineId(self):
		query = QSqlQuery(self.db)
		QueryExec(query, "SELECT id FROM machines WHERE pid = -1")
		if query.next():
			self.host_machine_id = query.value(0)
		else:
			self.host_machine_id = 0
		return self.host_machine_id

	def HostMachineId(self):
		if self.host_machine_id:
			return self.host_machine_id
		return self.GetHostMachineId()

	def SelectValue(self, sql):
		query = QSqlQuery(self.db)
		try:
			QueryExec(query, sql)
		except:
			return None
		if query.next():
			return Decimal(query.value(0))
		return None

	def SwitchesMinTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM context_switches"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id LIMIT 1")

	def SwitchesMaxTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM context_switches"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id DESC LIMIT 1")

	def SamplesMinTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM samples"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id LIMIT 1")

	def SamplesMaxTime(self, machine_id):
		return self.SelectValue("SELECT time"
					" FROM samples"
					" WHERE time != 0 AND machine_id = " + str(machine_id) +
					" ORDER BY id DESC LIMIT 1")

	def CallsMinTime(self, machine_id):
		return self.SelectValue("SELECT calls.call_time"
					" FROM calls"
					" INNER JOIN threads ON threads.thread_id = calls.thread_id"
					" WHERE calls.call_time != 0 AND threads.machine_id = " + str(machine_id) +
					" ORDER BY calls.id LIMIT 1")

	def CallsMaxTime(self, machine_id):
		return self.SelectValue("SELECT calls.return_time"
					" FROM calls"
					" INNER JOIN threads ON threads.thread_id = calls.thread_id"
					" WHERE calls.return_time != 0 AND threads.machine_id = " + str(machine_id) +
					" ORDER BY calls.return_time DESC LIMIT 1")

	def GetStartTime(self, machine_id):
		t0 = self.SwitchesMinTime(machine_id)
		t1 = self.SamplesMinTime(machine_id)
		t2 = self.CallsMinTime(machine_id)
		if t0 is None or (not(t1 is None) and t1 < t0):
			t0 = t1
		if t0 is None or (not(t2 is None) and t2 < t0):
			t0 = t2
		return t0

	def GetFinishTime(self, machine_id):
		t0 = self.SwitchesMaxTime(machine_id)
		t1 = self.SamplesMaxTime(machine_id)
		t2 = self.CallsMaxTime(machine_id)
		if t0 is None or (not(t1 is None) and t1 > t0):
			t0 = t1
		if t0 is None or (not(t2 is None) and t2 > t0):
			t0 = t2
		return t0

	def HostStartTime(self):
		if self.host_start_time:
			return self.host_start_time
		self.host_start_time = self.GetStartTime(self.HostMachineId())
		return self.host_start_time

	def HostFinishTime(self):
		if self.host_finish_time:
			return self.host_finish_time
		self.host_finish_time = self.GetFinishTime(self.HostMachineId())
		return self.host_finish_time

	def StartTime(self, machine_id):
		if machine_id == self.HostMachineId():
			return self.HostStartTime()
		return self.GetStartTime(machine_id)

	def FinishTime(self, machine_id):
		if machine_id == self.HostMachineId():
			return self.HostFinishTime()
		return self.GetFinishTime(machine_id)

# Database reference

class DBRef():

	def __init__(self, is_sqlite3, dbname):
		self.is_sqlite3 = is_sqlite3
		self.dbname = dbname
		self.TRUE = "TRUE"
		self.FALSE = "FALSE"
		# SQLite prior to version 3.23 does not support TRUE and FALSE
		if self.is_sqlite3:
			self.TRUE = "1"
			self.FALSE = "0"

	def Open(self, connection_name):
		dbname = self.dbname
		if self.is_sqlite3:
			db = QSqlDatabase.addDatabase("QSQLITE", connection_name)
		else:
			db = QSqlDatabase.addDatabase("QPSQL", connection_name)
			opts = dbname.split()
			for opt in opts:
				if "=" in opt:
					opt = opt.split("=")
					if opt[0] == "hostname":
						db.setHostName(opt[1])
					elif opt[0] == "port":
						db.setPort(int(opt[1]))
					elif opt[0] == "username":
						db.setUserName(opt[1])
					elif opt[0] == "password":
						db.setPassword(opt[1])
					elif opt[0] == "dbname":
						dbname = opt[1]
				else:
					dbname = opt

		db.setDatabaseName(dbname)
		if not db.open():
			raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())
		return db, dbname

# Main

def Main():
	usage_str =	"exported-sql-viewer.py [--pyside-version-1] <database name>\n" \
			"   or: exported-sql-viewer.py --help-only"
	ap = argparse.ArgumentParser(usage = usage_str, add_help = False)
	ap.add_argument("--pyside-version-1", action='store_true')
	ap.add_argument("dbname", nargs="?")
	ap.add_argument("--help-only", action='store_true')
	args = ap.parse_args()

	if args.help_only:
		app = QApplication(sys.argv)
		mainwindow = HelpOnlyWindow()
		mainwindow.show()
		err = app.exec_()
		sys.exit(err)

	dbname = args.dbname
	if dbname is None:
		ap.print_usage()
		print("Too few arguments")
		sys.exit(1)

	is_sqlite3 = False
	try:
		f = open(dbname, "rb")
		if f.read(15) == b'SQLite format 3':
			is_sqlite3 = True
		f.close()
	except:
		pass

	dbref = DBRef(is_sqlite3, dbname)
	db, dbname = dbref.Open("main")
	glb = Glb(dbref, db, dbname)
	app = QApplication(sys.argv)
	glb.app = app
	mainwindow = MainWindow(glb)
	glb.mainwindow = mainwindow
	mainwindow.show()
	err = app.exec_()
	glb.ShutdownInstances()
	db.close()
	sys.exit(err)

if __name__ == "__main__":
	Main()
