From a856224cf3a555d3425a9b3e4fc2d0181781eabe Mon Sep 17 00:00:00 2001
From: jce <jce@unknown>
Date: Fri, 16 Aug 2002 01:33:27 +0000
Subject: [PATCH] farther.

---
 src/sinfo/sinfo.c | 342 ++++++++++++++++++++++++++++++++++++++++++++--
 src/sinfo/sinfo.h |  19 +++
 2 files changed, 352 insertions(+), 9 deletions(-)

diff --git a/src/sinfo/sinfo.c b/src/sinfo/sinfo.c
index bd24cfa0cc2..2303de7689b 100644
--- a/src/sinfo/sinfo.c
+++ b/src/sinfo/sinfo.c
@@ -25,6 +25,7 @@
 \*****************************************************************************/
 
 #include <src/sinfo/sinfo.h>
+#include <src/common/list.h>
 
 
 /********************
@@ -42,11 +43,17 @@ char* int_to_str( int num );
 
 int query_server( partition_info_msg_t ** part_pptr, node_info_msg_t ** node_pptr  );
 
+int build_min_max_string( char* buffer, int max, int min );
+
 void display_partition_info_long( List partitions );
 void display_partition_info( List partitions );
-void display_partition_summary (char* partition);
+void display_all_partition_summary( partition_info_msg_t* part_ptr, node_info_msg_t* node_ptr );
+void display_partition_summarys ( List partitions );
 void display_nodes_list( List nodes );
+int get_node_index( char* name );
+char* get_node_prefix( char* name, char* buffer );
 
+List group_node_list( node_info_msg_t* msg );
 void display_all_nodes( node_info_msg_t* node_msg );
 
 
@@ -69,6 +76,9 @@ main (int argc, char *argv[])
 
 	display_all_nodes( node_msg );
 	
+	display_all_partition_summary( partition_msg, node_msg );
+
+
 	exit (0);
 }
 
@@ -96,25 +106,244 @@ query_server( partition_info_msg_t ** part_pptr, node_info_msg_t ** node_pptr  )
 
 void display_all_nodes( node_info_msg_t* node_msg )
 {
-	List nodes = list_create( NULL );
-	int i = 0;
-	for (; i < node_msg-> record_count; i++ )
-		list_append( nodes, &(node_msg->node_array[i]) );
+	List nodes = group_node_list( node_msg );
+	ListIterator i = list_iterator_create( nodes );
+	List current;
 
-	display_nodes_list( nodes );
-}
+	printf( "%10s %10s %4s %10s %10s %5s %10s %s\n",
+			"Name", "State","CPUS", "MEMORY", "DISK", "WGHT", "PARTITION", "FEATURES");
+	printf( "--------------------------------------------------------------------------------\n");
 
+	while ( (current= list_next(i)) != NULL )
+	{
+		display_nodes_list( current );
+	}
+}
 
-/*
+/* node_name_string_from_list - analyzes a list of node_info_t* and 
+ * 		fills in a buffer with the appropriate nodename in a prefix[001-100]
+ * 		type format.
+ * @nodes - list of node_info_t* to analyze
+ * @buffer - a char buffer to store the string in.
+ *
+ * return - return on success return buffer, NULL on failure
  */
+
+char* 
+node_name_string_from_list( List nodes, char* buffer )
+{
+	char prefix[64], *current;
+	node_info_t* curr_node = NULL;
+	int last_index = 0;
+	int curr_index = 0;
+	bool multiple = false;
+	ListIterator i = list_iterator_create( nodes );
+
+	curr_node = list_next(i);
+	get_node_prefix( curr_node->name, prefix );
+
+	while( (curr_node = list_next(i) ) != NULL )
+	{
+		if ( strcmp( get_node_prefix( curr_node->name, buffer ), prefix ) != 0 )
+			return NULL;
+	}
+	current = buffer + strlen( buffer );
+	*current = '[';
+	current++;
+	
+	list_iterator_reset(i);
+	curr_node = list_next(i);
+	last_index = get_node_index( curr_node->name );
+	current += sprintf(current, "%d", last_index );
+	
+	while( (curr_node = list_next(i) ) != NULL )
+	{
+		if ( (curr_index = get_node_index( curr_node->name )) > -1 )
+		{
+			if ( curr_index != (last_index+1) )
+			{
+				if ( multiple )
+				{
+					current += sprintf( current, "-%d,%d", last_index, curr_index );
+					multiple = false;
+				}
+				else
+				{
+					current += sprintf( current, ",%d", curr_index );
+					multiple = false;
+				}
+			}
+			else
+				multiple = true;
+
+			last_index = curr_index;
+			
+		}
+		else return NULL;	
+	}
+
+	if ( multiple == true )
+	{
+		current += sprintf( current, "-%d", curr_index );
+	}
+	*current = ']'; current ++;
+	*current = '\0';
+
+	return buffer;
+}
+
+
+struct partition_summary*
+find_partition_summary( List l, char* name )
+{
+	ListIterator i = list_iterator_create(l);
+	struct partition_summary* current;
+	
+	while ( (current = list_next(i) ) != NULL )
+	{
+		if ( strcmp( current->info->name, name ) == 0 )
+			return current;
+	}
+	return NULL;
+}
+
+struct node_state_summary*
+find_node_state_summary( List l, enum node_states state )
+{
+	ListIterator i = list_iterator_create(l);
+	struct node_state_summary* current;
+	
+	while ( (current = list_next(i) ) != NULL )
+	{
+		if ( state == current->state )
+			return current;
+	}
+	return NULL;
+}
+
+void 
+display_all_partition_summary( partition_info_msg_t* part_ptr, node_info_msg_t* node_ptr )
+{
+	int i=0;
+	List partitions = list_create( NULL );
+
+	for ( i=0; i < part_ptr->record_count; i++ )
+	{
+		struct partition_summary* sum = (struct partition_summary*) malloc( sizeof(struct partition_summary));
+		sum->info = &part_ptr->partition_array[i];
+		sum->states = list_create( NULL );
+		list_append( partitions, sum );
+	}
+
+	for ( i=0; i < node_ptr->record_count; i++ )
+	{
+		node_info_t* ninfo = &node_ptr->node_array[i];
+		struct partition_summary* part_sum = find_partition_summary( partitions, ninfo->partition );
+		struct node_state_summary* node_sum = NULL;
+		
+		if ( part_sum == NULL )
+		{
+			/* This should never happen */
+			printf("Couldn't find the partition... this is bad news\n");
+			continue;
+		}
+	
+		if ( (node_sum = find_node_state_summary( part_sum->states, (enum node_states)ninfo->node_state ) ) != NULL )
+		{
+			node_sum->state = (enum node_states)ninfo->node_state;
+			node_sum->cpu_max = MAX( ninfo->cpus, node_sum->cpu_max );
+			node_sum->cpu_min = MIN( ninfo->cpus, node_sum->cpu_min );
+			node_sum->ram_max = MAX( ninfo->real_memory, node_sum->ram_max );
+			node_sum->ram_min = MIN( ninfo->real_memory, node_sum->ram_min );
+			node_sum->disk_max = MAX( ninfo->tmp_disk, node_sum->disk_max);
+			node_sum->disk_min = MIN( ninfo->tmp_disk, node_sum->disk_min);
+			node_sum->node_count++;
+		}
+		else
+		{
+			node_sum = (struct node_state_summary*) malloc( sizeof(struct node_state_summary));
+			node_sum->state = (enum node_states)ninfo->node_state;
+			node_sum->cpu_max = ninfo->cpus;
+			node_sum->cpu_min = ninfo->cpus;
+			node_sum->ram_max = ninfo->real_memory;
+			node_sum->ram_min = ninfo->real_memory;
+			node_sum->disk_max = ninfo->tmp_disk;
+			node_sum->disk_min = ninfo->tmp_disk;
+			node_sum->node_count = 1;
+			list_append( part_sum->states, node_sum );
+		}
+	}
+
+	display_partition_summarys( partitions );
+}
+
 void 
-display_partition_summary (char* partition) 
+display_partition_summarys ( List partitions ) 
 {
+	const char* format_header = "%10s %8s %10s %8s %15s %15s\n"; 
+	const char* format =        "%10s %8d %10s %8s %15s %15s\n"; 
+	char cpu_buf[64];
+	char ram_buf[64];
+	char disk_buf[64];
+	char* no_name = "";
+
+	struct partition_summary* partition ;
+	ListIterator part_i = list_iterator_create( partitions );
 
+	printf( format_header, "Partition", "#Nodes", "Node State", "CPUs", "Memory", "TmpDisk" ); 
+	printf( "--------------------------------------------------------------------------------\n");
+
+	while ( (partition = list_next( part_i ) ) != NULL )
+	{
+		ListIterator node_i = list_iterator_create( partition->states );
+		struct node_state_summary* state_sum = NULL;
+		char* part_name = partition->info->name;
+		while ( ( state_sum = list_next(node_i) ) != NULL )
+		{
+			build_min_max_string( cpu_buf, state_sum->cpu_min, state_sum->cpu_max );
+			build_min_max_string( ram_buf, state_sum->ram_min, state_sum->ram_max );
+			build_min_max_string( disk_buf, state_sum->disk_min, state_sum->disk_max );
+			printf( format, part_name, state_sum->node_count, node_state_string( state_sum->state), cpu_buf, ram_buf, disk_buf ); 
+			part_name = no_name;
+		}
+		printf("\n");
+	}
 }
 
 void
 display_nodes_list( List nodes )
+{
+	/*int console_width = atoi( getenv( "COLUMNS" ) );*/
+	int console_width = 80;
+	char line[BUFSIZ];
+	char format[32];
+	char node_names[32];
+	node_info_t* curr = list_peek( nodes ) ;
+
+	node_name_string_from_list( nodes, node_names );
+
+
+	snprintf(line, BUFSIZ, "%10.10s %10.10s %4.4s %10.10s %10.10s %5.5s %10.10s %s",
+			node_names,
+			node_state_string( curr->node_state ), 
+			int_to_str( curr-> cpus ),
+			int_to_str( curr-> real_memory ),
+			int_to_str( curr-> tmp_disk ),
+			int_to_str( curr-> weight ),
+			curr-> partition,
+			curr-> features );
+
+	if ( params.line_wrap )
+		printf( "%s\n", line );
+	else
+	{
+		snprintf(format, 32, "%%.%ds\n", MAX(80,console_width) );
+		printf( format, line );
+	}
+}
+	
+void
+display_nodes_list_long( List nodes )
 {
 	/*int console_width = atoi( getenv( "COLUMNS" ) );*/
 	int console_width = 80;
@@ -123,6 +352,8 @@ display_nodes_list( List nodes )
 	ListIterator i = list_iterator_create( nodes );
 	node_info_t* curr = NULL ;
 
+	printf( "%s\n", node_name_string_from_list( nodes, line ) );
+
 	printf( "%10s %10s %4s %10s %10s %5s %10s %s\n",
 			"Name", "State","CPUS", "MEMORY", "DISK", "WGHT", "PARTITION", "FEATURES");
 	printf( "--------------------------------------------------------------------------------\n");
@@ -153,6 +384,57 @@ display_nodes_list( List nodes )
 
 }
 
+List
+group_node_list( node_info_msg_t* msg )
+{
+	List node_lists = list_create( NULL );
+	node_info_t* nodes = msg->node_array;
+	int i;
+	
+	for ( i=0; i < msg->record_count; i++ )
+	{
+		ListIterator list_i = list_iterator_create( node_lists );
+		List curr_list = NULL;
+
+		while ( (curr_list = list_next(list_i)) != NULL )
+		{
+			node_info_t* curr = list_peek( curr_list ); 		
+			bool feature_test; 
+			bool part_test; 
+			
+			if ( curr->features != NULL && nodes[i].features != NULL )
+				feature_test = strcmp(nodes[i].features, curr->features) ? false : true ;
+			else if ( curr->features == nodes[i].features )
+				feature_test = true;
+			else feature_test = false;
+			if ( curr->partition != NULL && nodes[i].partition != NULL )
+				part_test = strcmp(nodes[i].partition, curr->partition) ? false : true ;	
+			else if ( curr->partition == nodes[i].partition )
+				part_test = true;
+			else part_test = false;
+			
+			if ( feature_test && part_test &&
+					nodes[i].node_state == curr->node_state &&
+					nodes[i].cpus == curr->cpus  &&
+					nodes[i].real_memory == curr->real_memory  &&
+					nodes[i].tmp_disk == curr->tmp_disk )
+			{
+				list_append( curr_list, &( nodes[i] ));
+				break;
+			}
+		}
+		
+		if ( curr_list == NULL )
+		{
+			List temp = list_create( NULL ) ;
+			list_append( temp,  &( nodes[i]) );
+			list_append( node_lists, temp ); 
+		}
+	}
+
+	return node_lists;
+}
+
 void
 display_partition_info( List partitions )
 {
@@ -194,3 +476,45 @@ int_to_str( int num )
 	int_to_str_current = int_to_str_current + size+1;
 	return temp;	
 }
+
+
+char* 
+get_node_prefix( char* name, char* buffer )
+{
+	int length = strlen(name);
+	int i;
+	char* temp;
+
+	for ( i=0; i < length; i++ )
+	{
+		if ( name[i] >= '0' && name[i] <= '9' )
+			break;		
+	}
+
+	temp = strncpy( buffer, name, i );
+	temp[i] = '\0';
+	
+	return temp;
+}
+
+int 
+get_node_index( char* name )
+{
+	char* curr = name;
+
+	while ( ( *curr < '0' || *curr > '9' ) && *curr != '\0' )
+		curr++ ;
+	
+	return atoi( curr );
+
+}
+
+int
+build_min_max_string( char* buffer, int min, int max )
+{
+	if ( max == min )
+		return sprintf( buffer, "%d", max );
+	
+	return sprintf( buffer, "%d-%d", min, max );
+}
+
diff --git a/src/sinfo/sinfo.h b/src/sinfo/sinfo.h
index 06ece4cd7af..3c45bf784de 100644
--- a/src/sinfo/sinfo.h
+++ b/src/sinfo/sinfo.h
@@ -53,6 +53,9 @@
 #include <src/common/xmalloc.h>
 #include <src/common/list.h>
 
+
+#define MIN(x,y) (((x)<(y))?(x):(y))
+
 struct sinfo_parameters {
 	bool partition_flag;
 	const char* partition;
@@ -65,6 +68,22 @@ struct sinfo_parameters {
 	int verbose;
 };
 
+struct node_state_summary {
+	enum node_states state;
+	uint32_t node_count;
+	uint32_t cpu_min;
+	uint32_t cpu_max;
+	uint32_t ram_min;
+	uint32_t ram_max;
+	uint32_t disk_min;
+	uint32_t disk_max;
+};
+
+struct partition_summary {
+	partition_info_t* info;
+	List states;
+};
+
 int parse_state( char* str, enum job_states* states );
 int parse_command_line( int argc, char* argv[] );
 void print_options();
-- 
GitLab