From 06f726214082f03d5735bbe50a2198a0f2970c3b Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 01:10:00 +0200 Subject: [PATCH 1/7] Sort performance boost Cached all variables used by sort functions --- qubesmanager/table_widgets.py | 215 ++++++++++++++++------------------ 1 file changed, 99 insertions(+), 116 deletions(-) diff --git a/qubesmanager/table_widgets.py b/qubesmanager/table_widgets.py index 8fca4f8..dd22d2d 100644 --- a/qubesmanager/table_widgets.py +++ b/qubesmanager/table_widgets.py @@ -24,8 +24,6 @@ from PyQt4 import QtGui # pylint: disable=import-error from PyQt4 import QtCore # pylint: disable=import-error # pylint: disable=too-few-public-methods -from qubesadmin import exc - power_order = QtCore.Qt.DescendingOrder update_order = QtCore.Qt.AscendingOrder @@ -70,23 +68,21 @@ class VmTypeWidget(VmIconWidget): def __init__(self, value, vm): super(VmTypeWidget.VmTypeItem, self).__init__() self.value = value - self.vm = vm + self.qid = vm.qid + self.name = vm.name def set_value(self, value): self.value = value #pylint: disable=too-many-return-statements def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.value == other.value: - return self.vm.name < other.vm.name - return self.value < other.value - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + elif self.value == other.value: + return self.name < other.name + return self.value < other.value def __init__(self, vm, parent=None): (icon_path, tooltip) = self.get_vm_icon(vm) @@ -120,23 +116,21 @@ class VmLabelWidget(VmIconWidget): def __init__(self, value, vm): super(VmLabelWidget.VmLabelItem, self).__init__() self.value = value - self.vm = vm + self.qid = vm.qid + self.name = vm.name def set_value(self, value): self.value = value #pylint: disable=too-many-return-statements def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.value == other.value: - return self.vm.name < other.vm.name - return self.value < other.value - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + elif self.value == other.value: + return self.name < other.name + return self.value < other.value def __init__(self, vm, parent=None): icon_path = self.get_vm_icon_path(vm) @@ -158,16 +152,13 @@ class VmNameItem(QtGui.QTableWidgetItem): self.setTextAlignment(QtCore.Qt.AlignVCenter) self.qid = vm.qid - #pylint: disable=too-many-return-statements def __lt__(self, other): - try: - if self.qid == 0: - return True - elif other.qid == 0: - return False - return super(VmNameItem, self).__lt__(other) - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + else: + return super(VmNameItem, self).__lt__(other) class VmStatusIcon(QtGui.QLabel): @@ -185,12 +176,16 @@ class VmStatusIcon(QtGui.QLabel): def set_on_icon(self): if self.vm.get_power_state() == "Running": icon = QtGui.QIcon(":/on.png") + self.status = 3 elif self.vm.get_power_state() in ["Paused", "Suspended"]: icon = QtGui.QIcon(":/paused.png") + self.status = 2 elif self.vm.get_power_state() in ["Transient", "Halting", "Dying"]: icon = QtGui.QIcon(":/transient.png") + self.status = 1 else: icon = QtGui.QIcon(":/off.png") + self.status = 0 icon_sz = QtCore.QSize(row_height * 0.5, row_height * 0.5) icon_pixmap = icon.pixmap(icon_sz) @@ -200,19 +195,19 @@ class VmStatusIcon(QtGui.QLabel): class VmInfoWidget(QtGui.QWidget): class VmInfoItem(QtGui.QTableWidgetItem): - def __init__(self, upd_info_item, vm): + def __init__(self, on_icon, upd_info_item, vm): super(VmInfoWidget.VmInfoItem, self).__init__() + self.on_icon = on_icon self.upd_info_item = upd_info_item self.vm = vm + self.qid = vm.qid + self.name = vm.name def __lt__(self, other): # pylint: disable=too-many-return-statements - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False self_val = self.upd_info_item.value @@ -221,21 +216,17 @@ class VmInfoWidget(QtGui.QWidget): if self.tableWidget().\ horizontalHeader().sortIndicatorOrder() == update_order: # the result will be sorted by upd, sorting order: Ascending - self_val += 1 if self.vm.is_running() else 0 - other_val += 1 if other.vm.is_running() else 0 + self_val += 1 if self.on_icon.status > 0 else 0 + other_val += 1 if other.on_icon.status > 0 else 0 if self_val == other_val: - return self.vm.name < other.vm.name + return self.name < other.name return self_val > other_val elif self.tableWidget().\ horizontalHeader().sortIndicatorOrder() == power_order: # the result will be sorted by power state, # sorting order: Descending - self_val = -(self_val/10 + - 10*(1 if self.vm.is_running() else 0)) - other_val = -(other_val/10 + - 10*(1 if other.vm.is_running() else 0)) - if self_val == other_val: - return self.vm.name < other.vm.name + if self.on_icon.status == other.on_icon.status: + return self.name < other.name return self_val > other_val else: # it would be strange if this happened @@ -268,7 +259,7 @@ class VmInfoWidget(QtGui.QWidget): self.blk_icon.setVisible(False) self.error_icon.setVisible(False) - self.table_item = self.VmInfoItem(self.upd_info.table_item, vm) + self.table_item = self.VmInfoItem(self.on_icon, self.upd_info.table_item, vm) def update_vm_state(self): self.on_icon.update() @@ -280,6 +271,8 @@ class VmTemplateItem(QtGui.QTableWidgetItem): super(VmTemplateItem, self).__init__() self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.qid = vm.qid + self.name = vm.name self.setTextAlignment(QtCore.Qt.AlignVCenter) self.update() @@ -295,16 +288,13 @@ class VmTemplateItem(QtGui.QTableWidgetItem): self.setText(self.vm.klass) def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.text() == other.text(): - return self.vm.name < other.vm.name - return super(VmTemplateItem, self).__lt__(other) - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + elif self.text() == other.text(): + return self.name < other.name + return super(VmTemplateItem, self).__lt__(other) class VmNetvmItem(QtGui.QTableWidgetItem): @@ -312,6 +302,8 @@ class VmNetvmItem(QtGui.QTableWidgetItem): super(VmNetvmItem, self).__init__() self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.qid = vm.qid + self.name = vm.name self.setTextAlignment(QtCore.Qt.AlignVCenter) self.update() @@ -322,16 +314,13 @@ class VmNetvmItem(QtGui.QTableWidgetItem): self.setText(self.vm.netvm.name) def __lt__(self, other): - try: - if self.vm.qid == 0: + if self.qid == 0: return True - elif other.vm.qid == 0: + elif other.qid == 0: return False elif self.text() == other.text(): - return self.vm.name < other.vm.name + return self.name < other.name return super(VmNetvmItem, self).__lt__(other) - except exc.QubesPropertyAccessError: - return False class VmInternalItem(QtGui.QTableWidgetItem): @@ -340,6 +329,7 @@ class VmInternalItem(QtGui.QTableWidgetItem): self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.qid = vm.qid self.update() def update(self): @@ -348,14 +338,11 @@ class VmInternalItem(QtGui.QTableWidgetItem): def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - return super(VmInternalItem, self).__lt__(other) - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + return super(VmInternalItem, self).__lt__(other) # features man qvm-features @@ -365,6 +352,8 @@ class VmUpdateInfoWidget(QtGui.QWidget): super(VmUpdateInfoWidget.VmUpdateInfoItem, self).__init__() self.value = 0 self.vm = vm + self.qid = vm.qid + self.name = vm.name self.set_value(value) def set_value(self, value): @@ -376,16 +365,13 @@ class VmUpdateInfoWidget(QtGui.QWidget): self.value = 0 def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.value == other.value: - return self.vm.name < other.vm.name - return self.value < other.value - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + elif self.value == other.value: + return self.name < other.name + return self.value < other.value def __init__(self, vm, show_text=True, parent=None): super(VmUpdateInfoWidget, self).__init__(parent) @@ -473,6 +459,8 @@ class VmSizeOnDiskItem(QtGui.QTableWidgetItem): self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.qid = vm.qid + self.name = vm.name self.value = 0 self.update() self.setTextAlignment(QtCore.Qt.AlignVCenter) @@ -486,16 +474,13 @@ class VmSizeOnDiskItem(QtGui.QTableWidgetItem): self.setText(str(self.value) + " MiB") def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.value == other.value: - return self.vm.name < other.vm.name - return self.value < other.value - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + elif self.value == other.value: + return self.name < other.name + return self.value < other.value class VmIPItem(QtGui.QTableWidgetItem): @@ -504,6 +489,7 @@ class VmIPItem(QtGui.QTableWidgetItem): self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.qid = vm.qid self.update() def update(self): @@ -511,14 +497,11 @@ class VmIPItem(QtGui.QTableWidgetItem): self.setText(self.ip if self.ip is not None else 'n/a') def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - return super(VmIPItem, self).__lt__(other) - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + return super(VmIPItem, self).__lt__(other) class VmIncludeInBackupsItem(QtGui.QTableWidgetItem): @@ -527,25 +510,26 @@ class VmIncludeInBackupsItem(QtGui.QTableWidgetItem): self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.name = vm.name + self.qid = vm.qid self.update() def update(self): if getattr(self.vm, 'include_in_backups', None): self.setText("Yes") + self.include_in_backups = True else: self.setText("") + self.include_in_backups = False def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.vm.include_in_backups == other.vm.include_in_backups: - return self.vm.name < other.vm.name - return self.vm.include_in_backups < other.vm.include_in_backups - except exc.QubesPropertyAccessError: + if self.vm.qid == 0: + return True + elif other.qid == 0: return False + elif self.include_in_backups == other.include_in_backups: + return self.name < other.name + return self.include_in_backups < other.include_in_backups class VmLastBackupItem(QtGui.QTableWidgetItem): @@ -554,6 +538,8 @@ class VmLastBackupItem(QtGui.QTableWidgetItem): self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.vm = vm + self.qid = vm.qid + self.name = vm.name self.update() def update(self): @@ -567,17 +553,14 @@ class VmLastBackupItem(QtGui.QTableWidgetItem): #pylint: disable=too-many-return-statements def __lt__(self, other): - try: - if self.vm.qid == 0: - return True - elif other.vm.qid == 0: - return False - elif self.backup_timestamp == other.backup_timestamp: - return self.vm.name < other.vm.name - elif not self.backup_timestamp: - return False - elif not other.backup_timestamp: - return True - return self.backup_timestamp < other.backup_timestamp - except exc.QubesPropertyAccessError: + if self.qid == 0: + return True + elif other.qid == 0: return False + elif self.backup_timestamp == other.backup_timestamp: + return self.name < other.name + elif not self.backup_timestamp: + return False + elif not other.backup_timestamp: + return True + return self.backup_timestamp < other.backup_timestamp From bd919e44c1c56fc717a656429eb5f9749755eea8 Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 01:17:48 +0200 Subject: [PATCH 2/7] Protect update() from accesing deleted domains --- qubesmanager/qube_manager.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index c3e8f07..66fa99f 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -139,15 +139,21 @@ class VmRowInTable(object): widget will extract the data from VM object :return: None """ - self.info_widget.update_vm_state() - self.template_widget.update() - self.netvm_widget.update() - self.internal_widget.update() - self.ip_widget.update() - self.include_in_backups_widget.update() - self.last_backup_widget.update() - if update_size_on_disk: - self.size_widget.update() + try: + self.info_widget.update_vm_state() + self.template_widget.update() + self.netvm_widget.update() + self.internal_widget.update() + self.ip_widget.update() + self.include_in_backups_widget.update() + self.last_backup_widget.update() + if update_size_on_disk: + self.size_widget.update() + except exc.QubesPropertyAccessError: + pass + + #force re-sorting + self.table.setSortingEnabled(True) vm_shutdown_timeout = 20000 # in msec From 632f23c29841cad26b404a09d592b57892bfee73 Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 01:19:20 +0200 Subject: [PATCH 3/7] Removed unneeded try/except --- qubesmanager/qube_manager.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index 66fa99f..fefe5ac 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -969,12 +969,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow): settings_window = settings.VMSettingsWindow( vm, self.qt_app, "basic") settings_window.exec_() - - # vm could be deleted on renaming - try: - self.vms_in_table[vm.qid].update() - except exc.QubesPropertyAccessError: - pass + self.vms_in_table[vm.qid].update() # noinspection PyArgumentList From 14f58fe8c1ed723c77be99e6119a57e195c3145d Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 01:21:04 +0200 Subject: [PATCH 4/7] Avoid lag on loading dialog --- qubesmanager/qube_manager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index fefe5ac..b1dbbab 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -546,8 +546,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow): vm_row = VmRowInTable(vm, row_no, self.table) vms_in_table[vm.qid] = vm_row row_no += 1 - if row_no % 5 == 0: - self.qt_app.processEvents() + self.qt_app.processEvents() self.vms_list = vms_list self.vms_in_table = vms_in_table From 1d80837cd072831e357088514f7564a3d39ce200 Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 01:22:28 +0200 Subject: [PATCH 5/7] Removed unneeded manual sort Same its called later during init process --- qubesmanager/qube_manager.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index b1dbbab..8fcbb65 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -313,9 +313,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow): QtGui.QHeaderView.Interactive) self.table.horizontalHeader().setStretchLastSection(True) - self.table.sortItems(self.columns_indices[self.sort_by_column], - self.sort_order) - self.context_menu = QtGui.QMenu(self) self.context_menu.addAction(self.action_settings) From 5ddd029d344db057304cd4b59e4b9b0c1a11c7cf Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 01:26:34 +0200 Subject: [PATCH 6/7] Fix minor performance bug --- qubesmanager/table_widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubesmanager/table_widgets.py b/qubesmanager/table_widgets.py index dd22d2d..ab0ec44 100644 --- a/qubesmanager/table_widgets.py +++ b/qubesmanager/table_widgets.py @@ -523,7 +523,7 @@ class VmIncludeInBackupsItem(QtGui.QTableWidgetItem): self.include_in_backups = False def __lt__(self, other): - if self.vm.qid == 0: + if self.qid == 0: return True elif other.qid == 0: return False From d886983c0297fe281c277ff2f36863e863ab9ebb Mon Sep 17 00:00:00 2001 From: donoban Date: Thu, 12 Jul 2018 02:00:17 +0200 Subject: [PATCH 7/7] Fixed identation and other problems on merge --- qubesmanager/table_widgets.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/qubesmanager/table_widgets.py b/qubesmanager/table_widgets.py index 906f53f..4dd5538 100644 --- a/qubesmanager/table_widgets.py +++ b/qubesmanager/table_widgets.py @@ -157,8 +157,7 @@ class VmNameItem(QtGui.QTableWidgetItem): return True elif other.qid == 0: return False - else: - return super(VmNameItem, self).__lt__(other) + return super(VmNameItem, self).__lt__(other) class VmStatusIcon(QtGui.QLabel): @@ -197,7 +196,7 @@ class VmInfoWidget(QtGui.QWidget): class VmInfoItem(QtGui.QTableWidgetItem): def __init__(self, on_icon, upd_info_item, vm): super(VmInfoWidget.VmInfoItem, self).__init__() - self.on_icon = on_icon + self.on_icon = on_icon self.upd_info_item = upd_info_item self.vm = vm self.qid = vm.qid @@ -259,7 +258,8 @@ class VmInfoWidget(QtGui.QWidget): self.blk_icon.setVisible(False) self.error_icon.setVisible(False) - self.table_item = self.VmInfoItem(self.on_icon, self.upd_info.table_item, vm) + self.table_item = self.VmInfoItem(self.on_icon,\ + self.upd_info.table_item, vm) def update_vm_state(self): self.on_icon.update() @@ -314,13 +314,13 @@ class VmNetvmItem(QtGui.QTableWidgetItem): self.setText(self.vm.netvm.name) def __lt__(self, other): - if self.qid == 0: - return True - elif other.qid == 0: - return False - elif self.text() == other.text(): - return self.name < other.name - return super(VmNetvmItem, self).__lt__(other) + if self.qid == 0: + return True + elif other.qid == 0: + return False + elif self.text() == other.text(): + return self.name < other.name + return super(VmNetvmItem, self).__lt__(other) class VmInternalItem(QtGui.QTableWidgetItem):