11use crate :: common:: format:: human_size;
2+ use crate :: dashboard:: ui:: screens:: cluster:: worker:: UtilizationRenderMode ;
23use ratatui:: layout:: { Constraint , Rect } ;
34use ratatui:: style:: Style ;
45use ratatui:: widgets:: { Cell , Row , Table } ;
56use std:: cmp;
67use tako:: hwstats:: MemoryStats ;
8+ use tako:: resources:: ResourceIndex ;
79
810use crate :: dashboard:: ui:: styles;
911use crate :: dashboard:: ui:: terminal:: DashboardFrame ;
1012use crate :: dashboard:: ui:: widgets:: progressbar:: {
11- ProgressPrintStyle , get_progress_bar_color, render_progress_bar_at,
13+ ProgressPrintStyle , get_progress_bar_color, get_progress_bar_cpu_color , render_progress_bar_at,
1214} ;
1315use crate :: dashboard:: utils:: calculate_average;
1416
@@ -19,6 +21,8 @@ const CPU_METER_WIDTH: u8 = CPU_METER_PROGRESSBAR_WIDTH + 4;
1921pub fn render_cpu_util_table (
2022 cpu_util_list : & [ f64 ] ,
2123 mem_util : & MemoryStats ,
24+ used_cpus : & [ ResourceIndex ] ,
25+ util_render_mode : & UtilizationRenderMode ,
2226 rect : Rect ,
2327 frame : & mut DashboardFrame ,
2428 table_style : Style ,
@@ -31,38 +35,50 @@ pub fn render_cpu_util_table(
3135 let width = constraints. len ( ) ;
3236 let height = ( cpu_util_list. len ( ) as f64 / width as f64 ) . ceil ( ) as usize ;
3337
34- let mut rows: Vec < Vec < ( f64 , usize ) > > = vec ! [ vec![ ] ; height] ;
35- for ( position, & cpu_util) in cpu_util_list. iter ( ) . enumerate ( ) {
36- let row = position % height;
37- rows[ row] . push ( ( cpu_util, position) ) ;
38+ let mut rows: Vec < Vec < ( f64 , usize , bool ) > > = vec ! [ vec![ ] ; height] ;
39+ if * util_render_mode == UtilizationRenderMode :: Worker {
40+ rows = get_utilization_sorted_by_usage ( cpu_util_list, used_cpus, height)
41+ } else {
42+ for ( position, & cpu_util) in cpu_util_list. iter ( ) . enumerate ( ) {
43+ let row = position % height;
44+ let used = used_cpus. contains ( & ResourceIndex :: new ( position as u32 ) ) ;
45+ rows[ row] . push ( ( cpu_util, position, used) ) ;
46+ }
3847 }
3948
4049 let rows: Vec < Row > = rows
4150 . into_iter ( )
4251 . map ( |targets| {
4352 let columns: Vec < Cell > = targets
4453 . into_iter ( )
45- . map ( |( cpu_util, position) | {
54+ . map ( |( cpu_util, position, used ) | {
4655 let progress = cpu_util / 100.00 ;
56+ let style = match util_render_mode {
57+ UtilizationRenderMode :: Global => get_progress_bar_color ( progress) ,
58+ UtilizationRenderMode :: Worker => get_progress_bar_cpu_color ( progress, used) ,
59+ } ;
60+
4761 Cell :: from ( render_progress_bar_at (
4862 Some ( format ! ( "{position:>3} " ) ) ,
4963 progress,
5064 CPU_METER_PROGRESSBAR_WIDTH ,
5165 ProgressPrintStyle :: default ( ) ,
5266 ) )
53- . style ( get_progress_bar_color ( progress ) )
67+ . style ( style )
5468 } )
5569 . collect ( ) ;
5670 Row :: new ( columns)
5771 } )
5872 . collect ( ) ;
5973
60- let avg_cpu = calculate_average ( cpu_util_list) ;
61-
6274 let mem_used = mem_util. total - mem_util. free ;
75+ let ( which_util, num_cpus, avg_cpu) =
76+ create_title_info ( cpu_util_list, used_cpus, util_render_mode) ;
77+
6378 let title = styles:: table_title ( format ! (
64- "Worker Utilization ({} CPUs), Avg CPU = {:.0}%, Mem = {:.0}% ({}/{})" ,
65- cpu_util_list. len( ) ,
79+ "{} Utilization ({} CPUs), Avg CPU = {:.0}%, Mem = {:.0}% ({}/{})" ,
80+ which_util,
81+ num_cpus,
6682 avg_cpu,
6783 ( mem_used as f64 / mem_util. total as f64 ) * 100.0 ,
6884 human_size( mem_used) ,
@@ -89,3 +105,63 @@ fn get_column_constraints(rect: Rect, num_cpus: usize) -> Vec<Constraint> {
89105 )
90106 . collect ( )
91107}
108+
109+ fn get_utilization_sorted_by_usage (
110+ cpu_util_list : & [ f64 ] ,
111+ used_cpus : & [ ResourceIndex ] ,
112+ height : usize ,
113+ ) -> Vec < Vec < ( f64 , usize , bool ) > > {
114+ let mut all_cpus: Vec < ( f64 , usize , bool ) > = cpu_util_list
115+ . iter ( )
116+ . enumerate ( )
117+ . map ( |( position, & cpu_util) | {
118+ let used = used_cpus. contains ( & ResourceIndex :: new ( position as u32 ) ) ;
119+ ( cpu_util, position, used)
120+ } )
121+ . collect ( ) ;
122+
123+ all_cpus. sort_by_key ( |& ( _, _, used) | std:: cmp:: Reverse ( used) ) ;
124+
125+ let mut rows: Vec < Vec < ( f64 , usize , bool ) > > = vec ! [ vec![ ] ; height] ;
126+ for ( index, cpu_data) in all_cpus. into_iter ( ) . enumerate ( ) {
127+ let row = index % height;
128+ rows[ row] . push ( cpu_data) ;
129+ }
130+ rows
131+ }
132+
133+ fn create_title_info (
134+ cpu_util_list : & [ f64 ] ,
135+ used_cpus : & [ ResourceIndex ] ,
136+ util_render_mode : & UtilizationRenderMode ,
137+ ) -> ( String , usize , f64 ) {
138+ let which_util = match util_render_mode {
139+ UtilizationRenderMode :: Global => "Node" . to_string ( ) ,
140+ UtilizationRenderMode :: Worker => "Worker" . to_string ( ) ,
141+ } ;
142+
143+ let num_cpus = match util_render_mode {
144+ UtilizationRenderMode :: Global => cpu_util_list. len ( ) ,
145+ UtilizationRenderMode :: Worker => used_cpus. len ( ) ,
146+ } ;
147+
148+ let avg_usage = match util_render_mode {
149+ UtilizationRenderMode :: Global => calculate_average ( cpu_util_list) ,
150+ UtilizationRenderMode :: Worker => {
151+ let used_cpu_util_list: Vec < f64 > = cpu_util_list
152+ . iter ( )
153+ . enumerate ( )
154+ . filter_map ( |( idx, utilization) | {
155+ if used_cpus. contains ( & ResourceIndex :: new ( idx as u32 ) ) {
156+ Some ( * utilization)
157+ } else {
158+ None
159+ }
160+ } )
161+ . collect ( ) ;
162+ calculate_average ( & used_cpu_util_list)
163+ }
164+ } ;
165+
166+ ( which_util, num_cpus, avg_usage)
167+ }
0 commit comments