From 3687350e65b76a457c730c4c58485a4c2ec0453f Mon Sep 17 00:00:00 2001 From: desbma Date: Thu, 13 Nov 2014 01:35:02 +0100 Subject: [PATCH] Fix sorting by memory usage, IO rate, or name --- glances/core/glances_processes.py | 21 ++++++++++------ glances/plugins/glances_processlist.py | 33 +++++++++++++------------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/glances/core/glances_processes.py b/glances/core/glances_processes.py index b605d934..09596ddc 100644 --- a/glances/core/glances_processes.py +++ b/glances/core/glances_processes.py @@ -25,7 +25,6 @@ from glances.core.glances_timer import Timer, getTimeSinceLastUpdate import collections import psutil import re -import sys PROCESS_TREE = True # TODO remove that and take command line parameter @@ -44,7 +43,7 @@ class ProcessTreeNode(object): self.children = [] self.children_sorted = False self.sort_key = sort_key - self.reverse_sorting = True + self.reverse_sorting = (self.sort_key != "name") self.is_root = root def __str__(self): @@ -72,23 +71,29 @@ class ProcessTreeNode(object): return "\n".join(lines) def setSorting(self, key, reverse): + """ Set sorting key or func for user with __iter__. """ if (self.sort_key != key) or (self.reverse_sorting != reverse): self.children_sorted = False self.sort_key = key self.reverse_sorting = reverse def getRessourceUsage(self): - """ Return ressource usage for a process and all its children. """ - # special case for root - if self.is_root: - return sys.maxsize + """ Return "weight" of a process and all its children for sorting. """ + if self.sort_key == "name": + return self.stats[self.sort_key] # sum ressource usage for self and other total = 0 nodes_to_sum = collections.deque([self]) while nodes_to_sum: current_node = nodes_to_sum.pop() - total += current_node.stats[self.sort_key] + if callable(self.sort_key): + total += self.sort_key(current_node.stats) + elif self.sort_key == "io_counters": + stats = current_node.stats[self.sort_key] + total += stats[0] - stats[2] + stats[1] - stats[3] + else: + total += current_node.stats[self.sort_key] nodes_to_sum.extend(current_node.children) return total @@ -109,6 +114,8 @@ class ProcessTreeNode(object): if not self.is_root: yield self if not self.children_sorted: + # optimization to avoid sorting twice (once when limiting the maximum processes to grab stats for, + # and once before displaying) self.children.sort(key=__class__.getRessourceUsage, reverse=self.reverse_sorting) self.children_sorted = True for child in self.children: diff --git a/glances/plugins/glances_processlist.py b/glances/plugins/glances_processlist.py index b4ffd085..f0186d56 100644 --- a/glances/plugins/glances_processlist.py +++ b/glances/plugins/glances_processlist.py @@ -383,14 +383,14 @@ class Plugin(GlancesPlugin): self.tag_proc_time = True if PROCESS_TREE: - ret.extend(self.get_process_tree_curses_data(self.sortlist(process_sort_key), + ret.extend(self.get_process_tree_curses_data(self.sortstats(process_sort_key), args, first_level=True, max_node_count=glances_processes.get_max_processes())) else: # Loop over processes (sorted by the sort key previously compute) first = True - for p in self.sortlist(process_sort_key): + for p in self.sortstats(process_sort_key): ret.extend(self.get_process_curses_data(p, first, args)) # End of extended stats first = False @@ -398,20 +398,17 @@ class Plugin(GlancesPlugin): # Return the message with decoration return ret - def sortlist(self, sortedby=None): + def sortstats(self, sortedby=None): """Return the stats sorted by sortedby variable.""" if sortedby is None: # No need to sort... return self.stats - if PROCESS_TREE: - return self.stats # TODO fix that and implement dynamic sorting - sortedreverse = True if sortedby == 'name': sortedreverse = False - if sortedby == 'io_counters': + if sortedby == 'io_counters' and not PROCESS_TREE: # Specific case for io_counters # Sum of io_r + io_w try: @@ -427,15 +424,19 @@ class Plugin(GlancesPlugin): reverse=sortedreverse) else: # Others sorts - try: - listsorted = sorted(self.stats, - key=lambda process: process[sortedby], - reverse=sortedreverse) - except (KeyError, TypeError): - listsorted = sorted(self.stats, - key=lambda process: process['name'], - reverse=False) + if PROCESS_TREE: + self.stats.setSorting(sortedby, sortedreverse) + else: + try: + listsorted = sorted(self.stats, + key=lambda process: process[sortedby], + reverse=sortedreverse) + except (KeyError, TypeError): + listsorted = sorted(self.stats, + key=lambda process: process['name'], + reverse=False) - self.stats = listsorted + if not PROCESS_TREE: + self.stats = listsorted return self.stats