From 8a590a8d71ee7581277ec89e391168169f5a0d3b Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 19 Jan 2013 19:54:36 +0100 Subject: [PATCH] bex prun: Better allocation of display slots --- lib/bin/bex-prun | 94 +++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/lib/bin/bex-prun b/lib/bin/bex-prun index 685c8be..162fc8a 100755 --- a/lib/bin/bex-prun +++ b/lib/bin/bex-prun @@ -126,8 +126,8 @@ use Curses; my $C; my $nrows; -my @by_row = (); -my %by_host = (); +my @by_row; +my %by_host; my %host_state; my %host_cnt; @@ -138,6 +138,22 @@ my %job_cnt; my %host_last_fail_job; my %host_last_fail_stat; +my @states; +my %state_to_pri; + +BEGIN { + @by_row = (); + %by_host = (); + @states = qw(unknown ready running done failed); + %state_to_pri = ( + 'unknown' => 0, + 'ready' => 1, + 'done' => 2, + 'failed' => 3, + 'running' => 4, + ); +} + sub new($) { $C = new Curses; start_color; @@ -160,7 +176,7 @@ sub new($) { %host_state = %host_cnt = (); %job_state = %job_cnt = (); - for my $s ('unknown', 'ready', 'running', 'done', 'failed') { + for my $s (@states) { $host_cnt{$s} = 0; $job_cnt{'*'}{$s} = 0; } @@ -193,7 +209,7 @@ sub set_host_status($$$) { if (defined $prev_stat) { $host_cnt{$prev_stat}--; } else { - for my $s ('unknown', 'ready', 'running', 'done', 'failed') { $job_cnt{$mach}{$s} = 0; } + for my $s (@states) { $job_cnt{$mach}{$s} = 0; } } $host_state{$mach} = $stat; $host_cnt{$stat}++; @@ -228,41 +244,54 @@ sub refresh_status($) { sub get_slot($) { my ($mach) = @_; - my $s; - if (defined ($s = $by_host{$mach})) { - delete $s->{'Gone'}; - } else { - my ($best, $besti); - for my $i (0..$nrows-1) { - my $r = $by_row[$i]; - if (!defined $r) { - $besti = $i; - $best = undef; - last; - } elsif ($r->{'Gone'} && (!$best || $best->{'Gone'} > $r->{'Gone'})) { - $besti = $i; - $best = $r; - } - } - if ($best) { - delete $by_host{$best->{'Host'}}; - } - $s->{'Host'} = $mach; - $s->{'Row'} = $besti; - $by_host{$mach} = $s; - $by_row[$besti] = $s; + my $s = $by_host{$mach}; + if (!defined $s) { + $s = $by_host{$mach} = { 'Host' => $mach }; } return $s; } -my $gone_counter = 1; -sub delete_slot($) { +my $place_counter; + +sub place_slot($) { my ($s) = @_; - $s->{'Gone'} = $gone_counter++; + $s->{'LastUpdate'} = $place_counter++; + return $s if defined $s->{'Row'}; + + my $pri = $state_to_pri{$host_state{$s->{'Host'}}}; + my ($best, $besti); + my $bestpri = -1; + for my $i (0..$nrows-1) { + my $r = $by_row[$i]; + if (!defined $r) { + $besti = $i; + $best = undef; + last; + } + my $rpri = $state_to_pri{$host_state{$r->{'Host'}}}; + next if $rpri > $pri; + + if ($rpri < $bestpri || + $rpri == $bestpri && $r->{'LastUpdate'} < $best->{'LastUpdate'}) { + # Trick: $best must be defined, as otherwise $bestpri == -1 + $best = $r; + $besti = $i; + $bestpri = $rpri; + } + } + + if ($best) { + delete $best->{'Row'}; + } + $s->{'Row'} = $besti; + $by_row[$besti] = $s; + return $s; } sub redraw_slot($) { my ($s) = @_; + my $r = $s->{'Row'} // return; + $r++; my $mach = $s->{'Host'}; my $stat = $s->{'Status'} // "?"; my $jid = $s->{'Job'} // ""; @@ -281,7 +310,6 @@ sub redraw_slot($) { $C->bkgdset(0); } } - my $r = $s->{'Row'} + 1; $C->addstr($r, 0, sprintf("%-20.20s", $mach)); if ($jcnt->{'failed'}) { $C->bkgdset(COLOR_PAIR(4)); @@ -307,7 +335,6 @@ sub redraw_slot($) { sub update($$$$) { my ($ui, $mach, $jid, $stat) = @_; - my $s = get_slot($mach); given ($stat) { when ('READY') { # Pseudo-state generated internally @@ -351,9 +378,10 @@ sub update($$$$) { $ui->err("Received unknown job status $stat"); } } + my $s = get_slot($mach); $s->{'Job'} = $jid; $s->{'Status'} = $stat; + place_slot($s); redraw_slot($s); - if ($stat eq 'DONE') { delete_slot($s); } $ui->refresh_status; } -- 2.39.2