aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python/exported-sql-viewer.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/scripts/python/exported-sql-viewer.py')
-rwxr-xr-xtools/perf/scripts/python/exported-sql-viewer.py285
1 files changed, 272 insertions, 13 deletions
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py
index ed39a0153dd3..63b14b80ebcd 100755
--- a/tools/perf/scripts/python/exported-sql-viewer.py
+++ b/tools/perf/scripts/python/exported-sql-viewer.py
@@ -1702,6 +1702,265 @@ class SQLTableDialogDataItem():
1702 return False 1702 return False
1703 return True 1703 return True
1704 1704
1705# Line edit data item
1706
1707class LineEditDataItem(object):
1708
1709 def __init__(self, glb, label, placeholder_text, parent, id = ""):
1710 self.glb = glb
1711 self.label = label
1712 self.placeholder_text = placeholder_text
1713 self.parent = parent
1714 self.id = id
1715
1716 self.value = ""
1717
1718 self.widget = QLineEdit()
1719 self.widget.editingFinished.connect(self.Validate)
1720 self.widget.textChanged.connect(self.Invalidate)
1721 self.red = False
1722 self.error = ""
1723 self.validated = True
1724
1725 if placeholder_text:
1726 self.widget.setPlaceholderText(placeholder_text)
1727
1728 def TurnTextRed(self):
1729 if not self.red:
1730 palette = QPalette()
1731 palette.setColor(QPalette.Text,Qt.red)
1732 self.widget.setPalette(palette)
1733 self.red = True
1734
1735 def TurnTextNormal(self):
1736 if self.red:
1737 palette = QPalette()
1738 self.widget.setPalette(palette)
1739 self.red = False
1740
1741 def InvalidValue(self, value):
1742 self.value = ""
1743 self.TurnTextRed()
1744 self.error = self.label + " invalid value '" + value + "'"
1745 self.parent.ShowMessage(self.error)
1746
1747 def Invalidate(self):
1748 self.validated = False
1749
1750 def DoValidate(self, input_string):
1751 self.value = input_string.strip()
1752
1753 def Validate(self):
1754 self.validated = True
1755 self.error = ""
1756 self.TurnTextNormal()
1757 self.parent.ClearMessage()
1758 input_string = self.widget.text()
1759 if not len(input_string.strip()):
1760 self.value = ""
1761 return
1762 self.DoValidate(input_string)
1763
1764 def IsValid(self):
1765 if not self.validated:
1766 self.Validate()
1767 if len(self.error):
1768 self.parent.ShowMessage(self.error)
1769 return False
1770 return True
1771
1772 def IsNumber(self, value):
1773 try:
1774 x = int(value)
1775 except:
1776 x = 0
1777 return str(x) == value
1778
1779# Non-negative integer ranges dialog data item
1780
1781class NonNegativeIntegerRangesDataItem(LineEditDataItem):
1782
1783 def __init__(self, glb, label, placeholder_text, column_name, parent):
1784 super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent)
1785
1786 self.column_name = column_name
1787
1788 def DoValidate(self, input_string):
1789 singles = []
1790 ranges = []
1791 for value in [x.strip() for x in input_string.split(",")]:
1792 if "-" in value:
1793 vrange = value.split("-")
1794 if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
1795 return self.InvalidValue(value)
1796 ranges.append(vrange)
1797 else:
1798 if not self.IsNumber(value):
1799 return self.InvalidValue(value)
1800 singles.append(value)
1801 ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
1802 if len(singles):
1803 ranges.append(self.column_name + " IN (" + ",".join(singles) + ")")
1804 self.value = " OR ".join(ranges)
1805
1806# Dialog data item converted and validated using a SQL table
1807
1808class SQLTableDataItem(LineEditDataItem):
1809
1810 def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent):
1811 super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent)
1812
1813 self.table_name = table_name
1814 self.match_column = match_column
1815 self.column_name1 = column_name1
1816 self.column_name2 = column_name2
1817
1818 def ValueToIds(self, value):
1819 ids = []
1820 query = QSqlQuery(self.glb.db)
1821 stmt = "SELECT id FROM " + self.table_name + " WHERE " + self.match_column + " = '" + value + "'"
1822 ret = query.exec_(stmt)
1823 if ret:
1824 while query.next():
1825 ids.append(str(query.value(0)))
1826 return ids
1827
1828 def DoValidate(self, input_string):
1829 all_ids = []
1830 for value in [x.strip() for x in input_string.split(",")]:
1831 ids = self.ValueToIds(value)
1832 if len(ids):
1833 all_ids.extend(ids)
1834 else:
1835 return self.InvalidValue(value)
1836 self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")"
1837 if self.column_name2:
1838 self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )"
1839
1840# Sample time ranges dialog data item converted and validated using 'samples' SQL table
1841
1842class SampleTimeRangesDataItem(LineEditDataItem):
1843
1844 def __init__(self, glb, label, placeholder_text, column_name, parent):
1845 self.column_name = column_name
1846
1847 self.last_id = 0
1848 self.first_time = 0
1849 self.last_time = 2 ** 64
1850
1851 query = QSqlQuery(glb.db)
1852 QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1")
1853 if query.next():
1854 self.last_id = int(query.value(0))
1855 self.last_time = int(query.value(1))
1856 QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1")
1857 if query.next():
1858 self.first_time = int(query.value(0))
1859 if placeholder_text:
1860 placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time)
1861
1862 super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent)
1863
1864 def IdBetween(self, query, lower_id, higher_id, order):
1865 QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1")
1866 if query.next():
1867 return True, int(query.value(0))
1868 else:
1869 return False, 0
1870
1871 def BinarySearchTime(self, lower_id, higher_id, target_time, get_floor):
1872 query = QSqlQuery(self.glb.db)
1873 while True:
1874 next_id = int((lower_id + higher_id) / 2)
1875 QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
1876 if not query.next():
1877 ok, dbid = self.IdBetween(query, lower_id, next_id, "DESC")
1878 if not ok:
1879 ok, dbid = self.IdBetween(query, next_id, higher_id, "")
1880 if not ok:
1881 return str(higher_id)
1882 next_id = dbid
1883 QueryExec(query, "SELECT time FROM samples WHERE id = " + str(next_id))
1884 next_time = int(query.value(0))
1885 if get_floor:
1886 if target_time > next_time:
1887 lower_id = next_id
1888 else:
1889 higher_id = next_id
1890 if higher_id <= lower_id + 1:
1891 return str(higher_id)
1892 else:
1893 if target_time >= next_time:
1894 lower_id = next_id
1895 else:
1896 higher_id = next_id
1897 if higher_id <= lower_id + 1:
1898 return str(lower_id)
1899
1900 def ConvertRelativeTime(self, val):
1901 mult = 1
1902 suffix = val[-2:]
1903 if suffix == "ms":
1904 mult = 1000000
1905 elif suffix == "us":
1906 mult = 1000
1907 elif suffix == "ns":
1908 mult = 1
1909 else:
1910 return val
1911 val = val[:-2].strip()
1912 if not self.IsNumber(val):
1913 return val
1914 val = int(val) * mult
1915 if val >= 0:
1916 val += self.first_time
1917 else:
1918 val += self.last_time
1919 return str(val)
1920
1921 def ConvertTimeRange(self, vrange):
1922 if vrange[0] == "":
1923 vrange[0] = str(self.first_time)
1924 if vrange[1] == "":
1925 vrange[1] = str(self.last_time)
1926 vrange[0] = self.ConvertRelativeTime(vrange[0])
1927 vrange[1] = self.ConvertRelativeTime(vrange[1])
1928 if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]):
1929 return False
1930 beg_range = max(int(vrange[0]), self.first_time)
1931 end_range = min(int(vrange[1]), self.last_time)
1932 if beg_range > self.last_time or end_range < self.first_time:
1933 return False
1934 vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True)
1935 vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False)
1936 return True
1937
1938 def AddTimeRange(self, value, ranges):
1939 n = value.count("-")
1940 if n == 1:
1941 pass
1942 elif n == 2:
1943 if value.split("-")[1].strip() == "":
1944 n = 1
1945 elif n == 3:
1946 n = 2
1947 else:
1948 return False
1949 pos = findnth(value, "-", n)
1950 vrange = [value[:pos].strip() ,value[pos+1:].strip()]
1951 if self.ConvertTimeRange(vrange):
1952 ranges.append(vrange)
1953 return True
1954 return False
1955
1956 def DoValidate(self, input_string):
1957 ranges = []
1958 for value in [x.strip() for x in input_string.split(",")]:
1959 if not self.AddTimeRange(value, ranges):
1960 return self.InvalidValue(value)
1961 ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges]
1962 self.value = " OR ".join(ranges)
1963
1705# Report Dialog Base 1964# Report Dialog Base
1706 1965
1707class ReportDialogBase(QDialog): 1966class ReportDialogBase(QDialog):
@@ -1716,7 +1975,7 @@ class ReportDialogBase(QDialog):
1716 self.setWindowTitle(title) 1975 self.setWindowTitle(title)
1717 self.setMinimumWidth(600) 1976 self.setMinimumWidth(600)
1718 1977
1719 self.data_items = [SQLTableDialogDataItem(glb, *x, parent=self) for x in items] 1978 self.data_items = [x(glb, self) for x in items]
1720 1979
1721 self.partial = partial 1980 self.partial = partial
1722 1981
@@ -1751,7 +2010,9 @@ class ReportDialogBase(QDialog):
1751 2010
1752 def Ok(self): 2011 def Ok(self):
1753 vars = self.report_vars 2012 vars = self.report_vars
1754 vars.name = self.data_items[0].value 2013 for d in self.data_items:
2014 if d.id == "REPORTNAME":
2015 vars.name = d.value
1755 if not vars.name: 2016 if not vars.name:
1756 self.ShowMessage("Report name is required") 2017 self.ShowMessage("Report name is required")
1757 return 2018 return
@@ -1785,17 +2046,15 @@ class SelectedBranchDialog(ReportDialogBase):
1785 2046
1786 def __init__(self, glb, parent=None): 2047 def __init__(self, glb, parent=None):
1787 title = "Selected Branches" 2048 title = "Selected Branches"
1788 items = ( 2049 items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"),
1789 ("Report name:", "Enter a name to appear in the window title bar", "", "", "", ""), 2050 lambda g, p: SampleTimeRangesDataItem(g, "Time ranges:", "Enter time ranges", "samples.id", p),
1790 ("Time ranges:", "Enter time ranges", "<timeranges>", "", "samples.id", ""), 2051 lambda g, p: NonNegativeIntegerRangesDataItem(g, "CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "cpu", p),
1791 ("CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "<ranges>", "", "cpu", ""), 2052 lambda g, p: SQLTableDataItem(g, "Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", "", p),
1792 ("Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", ""), 2053 lambda g, p: SQLTableDataItem(g, "PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", "", p),
1793 ("PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", ""), 2054 lambda g, p: SQLTableDataItem(g, "TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", "", p),
1794 ("TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", ""), 2055 lambda g, p: SQLTableDataItem(g, "DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id", p),
1795 ("DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id"), 2056 lambda g, p: SQLTableDataItem(g, "Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id", p),
1796 ("Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id"), 2057 lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p))
1797 ("Raw SQL clause: ", "Enter a raw SQL WHERE clause", "", "", "", ""),
1798 )
1799 super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent) 2058 super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent)
1800 2059
1801# Event list 2060# Event list