@@ -25,8 +25,6 @@ ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, Users
2525 this -> displayList = Vector_new (klass , false, DEFAULT_SIZE );
2626
2727 this -> processTable = Hashtable_new (200 , false);
28- this -> displayTreeSet = Hashtable_new (200 , false);
29- this -> draftingTreeSet = Hashtable_new (200 , false);
3028 this -> needsSort = true;
3129
3230 this -> usersTable = usersTable ;
@@ -74,8 +72,6 @@ void ProcessList_done(ProcessList* this) {
7472 }
7573#endif
7674
77- Hashtable_delete (this -> draftingTreeSet );
78- Hashtable_delete (this -> displayTreeSet );
7975 Hashtable_delete (this -> processTable );
8076
8177 Vector_delete (this -> displayList );
@@ -195,144 +191,7 @@ void ProcessList_remove(ProcessList* this, const Process* p) {
195191 assert (Hashtable_count (this -> processTable ) == Vector_count (this -> processes ));
196192}
197193
198- // ProcessList_updateTreeSetLayer sorts this->displayTreeSet,
199- // relying only on itself.
200- //
201- // Algorithm
202- //
203- // The algorithm is based on `depth-first search`,
204- // even though `breadth-first search` approach may be more efficient on first glance,
205- // after comparison it may be not, as it's not safe to go deeper without first updating the tree structure.
206- // If it would be safe that approach would likely bring an advantage in performance.
207- //
208- // Each call of the function looks for a 'layer'. A 'layer' is a list of processes with the same depth.
209- // First it sorts a list. Then it runs the function recursively for each element of the sorted list.
210- // After that it updates the settings of processes.
211- //
212- // It relies on `leftBound` and `rightBound` as an optimization to cut the list size at the time it builds a 'layer'.
213- //
214- // It uses a temporary Hashtable `draftingTreeSet` because it's not safe to traverse a tree
215- // and at the same time make changes in it.
216- //
217- static void ProcessList_updateTreeSetLayer (ProcessList * this , unsigned int leftBound , unsigned int rightBound , unsigned int deep , unsigned int left , unsigned int right , unsigned int * index , unsigned int * treeIndex , int indent ) {
218-
219- // It's guaranteed that layer_size is enough space
220- // but most likely it needs less. Specifically on first iteration.
221- int layerSize = (right - left ) / 2 ;
222-
223- // check if we reach `children` of `leaves`
224- if (layerSize == 0 )
225- return ;
226-
227- Vector * layer = Vector_new (Vector_type (this -> displayList ), false, layerSize );
228-
229- // Find all processes on the same layer (process with the same `deep` value
230- // and included in a range from `leftBound` to `rightBound`).
231- //
232- // This loop also keeps track of left_bound and right_bound of these processes
233- // in order not to lose this information once the list is sorted.
234- //
235- // The variables left_bound and right_bound are different from what the values lhs and rhs represent.
236- // While left_bound and right_bound define a range of processes to look at, the values given by lhs and rhs are indices into an array
237- //
238- // In the below example note how filtering a range of indices i is different from filtering for processes in the bounds left_bound < x < right_bound …
239- //
240- // The nested tree set is sorted by left value, which is guaranteed upon entry/exit of this function.
241- //
242- // i | l | r
243- // 1 | 1 | 9
244- // 2 | 2 | 8
245- // 3 | 4 | 5
246- // 4 | 6 | 7
247- for (unsigned int i = leftBound ; i < rightBound ; i ++ ) {
248- Process * proc = (Process * )Hashtable_get (this -> displayTreeSet , i );
249- assert (proc );
250- if (proc && proc -> tree_depth == deep && proc -> tree_left > left && proc -> tree_right < right ) {
251- if (Vector_size (layer ) > 0 ) {
252- Process * previous_process = (Process * )Vector_get (layer , Vector_size (layer ) - 1 );
253-
254- // Make a 'right_bound' of previous_process in a layer the current process's index.
255- //
256- // Use 'tree_depth' as a temporal variable.
257- // It's safe to do as later 'tree_depth' will be renovated.
258- previous_process -> tree_depth = proc -> tree_index ;
259- }
260-
261- Vector_add (layer , proc );
262- }
263- }
264-
265- // The loop above changes just up to process-1.
266- // So the last process of the layer isn't updated by the above code.
267- //
268- // Thus, if present, set the `rightBound` to the last process on the layer
269- if (Vector_size (layer ) > 0 ) {
270- Process * previous_process = (Process * )Vector_get (layer , Vector_size (layer ) - 1 );
271- previous_process -> tree_depth = rightBound ;
272- }
273-
274- Vector_quickSort (layer );
275-
276- int size = Vector_size (layer );
277- for (int i = 0 ; i < size ; i ++ ) {
278- Process * proc = (Process * )Vector_get (layer , i );
279-
280- unsigned int idx = (* index )++ ;
281- int newLeft = (* treeIndex )++ ;
282-
283- int level = deep == 0 ? 0 : (int )deep - 1 ;
284- int currentIndent = indent == -1 ? 0 : indent | (1 << level );
285- int nextIndent = indent == -1 ? 0 : ((i < size - 1 ) ? currentIndent : indent );
286-
287- unsigned int newLeftBound = proc -> tree_index ;
288- unsigned int newRightBound = proc -> tree_depth ;
289- ProcessList_updateTreeSetLayer (this , newLeftBound , newRightBound , deep + 1 , proc -> tree_left , proc -> tree_right , index , treeIndex , nextIndent );
290-
291- int newRight = (* treeIndex )++ ;
292-
293- proc -> tree_left = newLeft ;
294- proc -> tree_right = newRight ;
295- proc -> tree_index = idx ;
296- proc -> tree_depth = deep ;
297-
298- if (indent == -1 ) {
299- proc -> indent = 0 ;
300- } else if (i == size - 1 ) {
301- proc -> indent = - currentIndent ;
302- } else {
303- proc -> indent = currentIndent ;
304- }
305-
306- Hashtable_put (this -> draftingTreeSet , proc -> tree_index , proc );
307-
308- // It's not strictly necessary to do this, but doing so anyways
309- // allows for checking the correctness of the inner workings.
310- Hashtable_remove (this -> displayTreeSet , newLeftBound );
311- }
312-
313- Vector_delete (layer );
314- }
315-
316- static void ProcessList_updateTreeSet (ProcessList * this ) {
317- unsigned int index = 0 ;
318- unsigned int tree_index = 1 ;
319-
320- const int vsize = Vector_size (this -> displayList );
321-
322- assert (Hashtable_count (this -> draftingTreeSet ) == 0 );
323- assert ((int )Hashtable_count (this -> displayTreeSet ) == vsize );
324-
325- ProcessList_updateTreeSetLayer (this , 0 , vsize , 0 , 0 , vsize * 2 + 1 , & index , & tree_index , -1 );
326-
327- Hashtable * tmp = this -> draftingTreeSet ;
328- this -> draftingTreeSet = this -> displayTreeSet ;
329- this -> displayTreeSet = tmp ;
330-
331- assert (Hashtable_count (this -> draftingTreeSet ) == 0 );
332- assert ((int )Hashtable_count (this -> displayTreeSet ) == vsize );
333- }
334-
335- static void ProcessList_buildTreeBranch (ProcessList * this , pid_t pid , int level , int indent , bool show , int * node_counter , int * node_index ) {
194+ static void ProcessList_buildTreeBranch (ProcessList * this , pid_t pid , int level , int indent , bool show ) {
336195 // On OpenBSD the kernel thread 'swapper' has pid 0.
337196 // Do not treat it as root of any tree.
338197 if (pid == 0 )
@@ -366,10 +225,6 @@ static void ProcessList_buildTreeBranch(ProcessList* this, pid_t pid, int level,
366225 for (int i = l ; i < r ; i ++ ) {
367226 Process * process = (Process * )Vector_get (this -> processes , i );
368227
369- int index = (* node_index )++ ;
370-
371- int lft = (* node_counter )++ ;
372-
373228 if (!show ) {
374229 process -> show = false;
375230 }
@@ -380,30 +235,17 @@ static void ProcessList_buildTreeBranch(ProcessList* this, pid_t pid, int level,
380235 assert (Vector_size (this -> displayList ) == s + 1 ); (void )s ;
381236
382237 int nextIndent = indent | (1 << level );
383- ProcessList_buildTreeBranch (this , process -> pid , level + 1 , (i < lastShown ) ? nextIndent : indent , process -> show && process -> showChildren , node_counter , node_index );
238+ ProcessList_buildTreeBranch (this , process -> pid , level + 1 , (i < lastShown ) ? nextIndent : indent , process -> show && process -> showChildren );
384239 if (i == lastShown ) {
385240 process -> indent = - nextIndent ;
386241 } else {
387242 process -> indent = nextIndent ;
388243 }
389244
390- int rht = (* node_counter )++ ;
391-
392- process -> tree_left = lft ;
393- process -> tree_right = rht ;
394245 process -> tree_depth = level + 1 ;
395- process -> tree_index = index ;
396- Hashtable_put (this -> displayTreeSet , index , process );
397246 }
398247}
399248
400- static int ProcessList_treeProcessCompare (const void * v1 , const void * v2 ) {
401- const Process * p1 = (const Process * )v1 ;
402- const Process * p2 = (const Process * )v2 ;
403-
404- return SPACESHIP_NUMBER (p1 -> tree_left , p2 -> tree_left );
405- }
406-
407249static int compareProcessByKnownParentThenNatural (const void * v1 , const void * v2 ) {
408250 const Process * p1 = (const Process * )v1 ;
409251 const Process * p2 = (const Process * )v2 ;
@@ -423,9 +265,6 @@ static int compareProcessByKnownParentThenNatural(const void* v1, const void* v2
423265static void ProcessList_buildTree (ProcessList * this ) {
424266 Vector_prune (this -> displayList );
425267
426- int node_counter = 1 ;
427- int node_index = 0 ;
428-
429268 // Mark root processes
430269 int vsize = Vector_size (this -> processes );
431270 for (int i = 0 ; i < vsize ; i ++ ) {
@@ -460,12 +299,8 @@ static void ProcessList_buildTree(ProcessList* this) {
460299 process = (Process * )Vector_get (this -> processes , i );
461300 process -> indent = 0 ;
462301 process -> tree_depth = 0 ;
463- process -> tree_left = node_counter ++ ;
464- process -> tree_index = node_index ++ ;
465302 Vector_add (this -> displayList , process );
466- Hashtable_put (this -> displayTreeSet , process -> tree_index , process );
467- ProcessList_buildTreeBranch (this , process -> pid , 0 , 0 , process -> showChildren , & node_counter , & node_index );
468- process -> tree_right = node_counter ++ ;
303+ ProcessList_buildTreeBranch (this , process -> pid , 0 , 0 , process -> showChildren );
469304 continue ;
470305 }
471306 }
@@ -658,13 +493,6 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
658493 // Set UID column width based on max UID.
659494 Process_setUidColumnWidth (maxUid );
660495
661- if (this -> settings -> ss -> treeView ) {
662- // Clear out the hashtable to avoid any left-over processes from previous build
663- //
664- // The sorting algorithm relies on the fact that
665- // len(this->displayTreeSet) == len(this->processes)
666- Hashtable_clear (this -> displayTreeSet );
667-
496+ if (this -> settings -> ss -> treeView )
668497 ProcessList_buildTree (this );
669- }
670498}
0 commit comments