$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77657 - trunk/tools/build/v2/engine
From: steven_at_[hidden]
Date: 2012-03-30 17:34:40
Author: steven_watanabe
Date: 2012-03-30 17:34:39 EDT (Fri, 30 Mar 2012)
New Revision: 77657
URL: http://svn.boost.org/trac/boost/changeset/77657
Log:
Combine -d+10 stats for INSTANCE modules by class.  Make stats correct for a separate chaining hash table.  The old version seems to have been for open addressing.
Text files modified: 
   trunk/tools/build/v2/engine/hash.c     |    86 +++++++++++++++++++++---------          
   trunk/tools/build/v2/engine/hash.h     |    17 +++++                                   
   trunk/tools/build/v2/engine/modules.c  |   111 ++++++++++++++++++++++++++++++++++++++- 
   trunk/tools/build/v2/engine/variable.c |     2                                         
   4 files changed, 184 insertions(+), 32 deletions(-)
Modified: trunk/tools/build/v2/engine/hash.c
==============================================================================
--- trunk/tools/build/v2/engine/hash.c	(original)
+++ trunk/tools/build/v2/engine/hash.c	2012-03-30 17:34:39 EDT (Fri, 30 Mar 2012)
@@ -305,21 +305,27 @@
     return hp;
 }
 
+void hashdone( struct hash * hp )
+{
+    if ( !hp )
+        return;
+    if ( DEBUG_MEM || DEBUG_PROFILE )
+        hashstat( hp );
+    hash_free( hp );
+}
+
 /*
- * hashdone() - free a hash table, given its handle
+ * hash_free() - free a hash table, given its handle
  */
 
 void
-hashdone( struct hash * hp )
+hash_free( struct hash * hp )
 {
     int i;
 
     if ( !hp )
         return;
 
-    if ( DEBUG_MEM || DEBUG_PROFILE )
-        hashstat( hp );
-
     if ( hp->tab.base )
         BJAM_FREE( (char *)hp->tab.base );
     for ( i = 0; i <= hp->items.list; ++i )
@@ -332,29 +338,59 @@
 
 static void hashstat( struct hash * hp )
 {
-    ITEM * * tab = hp->tab.base;
-    int nel = hp->tab.nel;
-    int count = 0;
-    int sets = 0;
-    int run = tab && ( tab[ nel - 1 ] != (ITEM *)0 );
-    int i;
-    int here;
+    struct hashstats stats[ 1 ];
+    hashstats_init( stats );
+    hashstats_add( stats, hp );
+    hashstats_print( stats, hp->name );
+}
 
-    for ( i = nel; i > 0; --i )
+void hashstats_init( struct hashstats * stats )
+{
+    stats->count = 0;
+    stats->num_items = 0;
+    stats->tab_size = 0;
+    stats->item_size = 0;
+    stats->sets = 0;
+}
+
+void hashstats_add( struct hashstats * stats, struct hash * hp )
+{
+    if ( hp )
     {
-        if ( ( here = ( *tab++ != (ITEM *)0 ) ) )
-            count++;
-        if ( here && !run )
-            sets++;
-        run = here;
+        ITEM * * tab = hp->tab.base;
+        int nel = hp->tab.nel;
+        int count = 0;
+        int sets = 0;
+        int i;
+
+        for ( i = 0; i < nel; ++i )
+        {
+            ITEM * item;
+            int here = 0;
+            for ( item = tab[ i ]; item != 0; item = item->hdr.next )
+                ++here;
+
+            count += here;
+            if ( here > 0 )
+                ++sets;
+        }
+
+        stats->count += count;
+        stats->sets += sets;
+        stats->num_items += hp->items.nel;
+        stats->tab_size += hp->tab.nel;
+        stats->item_size = hp->items.size;
     }
+}
 
+void hashstats_print( struct hashstats * stats, const char * name )
+{
     printf( "%s table: %d+%d+%d (%dK+%luK) items+table+hash, %f density\n",
-        hp->name,
-        count,
-        hp->items.nel,
-        hp->tab.nel,
-        hp->items.nel * hp->items.size / 1024,
-        (long unsigned)hp->tab.nel * sizeof( ITEM ** ) / 1024,
-        (float)count / (float)sets );
+        name,
+        stats->count,
+        stats->num_items,
+        stats->tab_size,
+        stats->num_items * stats->item_size / 1024,
+        (long unsigned)stats->tab_size * sizeof( ITEM ** ) / 1024,
+        (float)stats->count / (float)stats->sets );
 }
Modified: trunk/tools/build/v2/engine/hash.h
==============================================================================
--- trunk/tools/build/v2/engine/hash.h	(original)
+++ trunk/tools/build/v2/engine/hash.h	2012-03-30 17:34:39 EDT (Fri, 30 Mar 2012)
@@ -26,9 +26,10 @@
 struct hash * hashinit     ( int datalen, const char * name );
 
 /*
- * hashdone() - free a hash table, given its handle
+ * hash_free() - free a hash table, given its handle
  */
-void          hashdone     ( struct hash * hp );
+void hash_free( struct hash * hp );
+void hashdone( struct hash * hp );
 
 /*
  * hashenumerate() - call f(i, data) on each item, i in the hash
@@ -62,4 +63,16 @@
  */
 HASHDATA *    hash_find    ( struct hash * hp, OBJECT * key );
 
+struct hashstats {
+    int count;
+    int num_items;
+    int tab_size;
+    int item_size;
+    int sets;
+};
+
+void hashstats_init( struct hashstats * stats );
+void hashstats_add( struct hashstats * stats, struct hash * hp );
+void hashstats_print( struct hashstats * stats, const char * name );
+
 #endif
Modified: trunk/tools/build/v2/engine/modules.c
==============================================================================
--- trunk/tools/build/v2/engine/modules.c	(original)
+++ trunk/tools/build/v2/engine/modules.c	2012-03-30 17:34:39 EDT (Fri, 30 Mar 2012)
@@ -100,14 +100,14 @@
     if ( m->rules )
     {
         hashenumerate( m->rules, delete_rule_, (void *)0 );
-        hashdone( m->rules );
+        hash_free( m->rules );
         m->rules = 0;
     }
 
     if ( m->native_rules )
     {
         hashenumerate( m->native_rules, delete_native_rule, (void *)0 );
-        hashdone( m->native_rules );
+        hash_free( m->native_rules );
         m->native_rules = 0;
     }
 
@@ -126,19 +126,114 @@
         }
         BJAM_FREE( m->fixed_variables );
         m->fixed_variables = 0;
-        hashdone( m->variable_indices );
+        hash_free( m->variable_indices );
         m->variable_indices = 0;
     }
 
     if ( m->imported_modules )
     {
         hashenumerate( m->imported_modules, delete_imported_modules, (void *)0 );
-        hashdone( m->imported_modules );
+        hash_free( m->imported_modules );
         m->imported_modules = 0;
     }
 }
 
 
+struct module_stats
+{
+    OBJECT * module_name;
+    struct hashstats rules_stats[ 1 ];
+    struct hashstats variables_stats[ 1 ];
+    struct hashstats variable_indices_stats[ 1 ];
+    struct hashstats imported_modules_stats[ 1 ];
+};
+
+
+static void module_stat( struct hash * hp, OBJECT * module, const char * name )
+{
+    if ( hp )
+    {
+        struct hashstats stats[ 1 ];
+        string id[ 1 ];
+        hashstats_init( stats );
+        string_new( id );
+        string_append( id, object_str( module ) );
+        string_push_back( id, ' ' );
+        string_append( id, name );
+
+        hashstats_add( stats, hp );
+        hashstats_print( stats, id->value );
+
+        string_free( id );
+    }
+}
+
+
+static void class_module_stat( struct hashstats * stats, OBJECT * module, const char * name )
+{
+    if ( stats->item_size )
+    {
+        string id[ 1 ];
+        string_new( id );
+        string_append( id, object_str( module ) );
+        string_append( id, " object " );
+        string_append( id, name );
+
+        hashstats_print( stats, id->value );
+
+        string_free( id );
+    }
+}
+
+
+static void stat_module( void * xmodule, void * data )
+{
+    module_t *m = (module_t *)xmodule;
+
+    if ( DEBUG_MEM || DEBUG_PROFILE )
+    {
+        struct hash * class_info = (struct hash *)data;
+        if ( m->class_module )
+        {
+            int found;
+            struct module_stats * ms = (struct module_stats *)hash_insert( class_info, m->class_module->name, &found );
+            if ( !found )
+            {
+                ms->module_name = m->class_module->name;
+                hashstats_init( ms->rules_stats );
+                hashstats_init( ms->variables_stats );
+                hashstats_init( ms->variable_indices_stats );
+                hashstats_init( ms->imported_modules_stats );
+            }
+
+            hashstats_add( ms->rules_stats, m->rules );
+            hashstats_add( ms->variables_stats, m->variables );
+            hashstats_add( ms->variable_indices_stats, m->variable_indices );
+            hashstats_add( ms->imported_modules_stats, m->imported_modules );
+        }
+        else
+        {
+            module_stat( m->rules, m->name, "rules" );
+            module_stat( m->variables, m->name, "variables" );
+            module_stat( m->variable_indices, m->name, "fixed variables" );
+            module_stat( m->imported_modules, m->name, "imported modules" );
+        }
+    }
+
+    delete_module( m );
+    object_free( m->name );
+}
+
+static void print_class_stats( void * xstats, void * data )
+{
+    struct module_stats * stats = (struct module_stats *)xstats;
+    class_module_stat( stats->rules_stats, stats->module_name, "rules" );
+    class_module_stat( stats->variables_stats, stats->module_name, "variables" );
+    class_module_stat( stats->variable_indices_stats, stats->module_name, "fixed variables" );
+    class_module_stat( stats->imported_modules_stats, stats->module_name, "imported modules" );
+}
+
+
 static void delete_module_( void * xmodule, void * data )
 {
     module_t *m = (module_t *)xmodule;
@@ -147,8 +242,16 @@
     object_free( m->name );
 }
 
+
 void modules_done()
 {
+    if ( DEBUG_MEM || DEBUG_PROFILE )
+    {
+        struct hash * class_hash = hashinit( sizeof( struct module_stats ), "object info" );
+        hashenumerate( module_hash, stat_module, (void *)class_hash );
+        hashenumerate( class_hash, print_class_stats, (void *)0 );
+        hash_free( class_hash );
+    }
     hashenumerate( module_hash, delete_module_, (void *)0 ); 
     hashdone( module_hash );
     module_hash = 0;
Modified: trunk/tools/build/v2/engine/variable.c
==============================================================================
--- trunk/tools/build/v2/engine/variable.c	(original)
+++ trunk/tools/build/v2/engine/variable.c	2012-03-30 17:34:39 EDT (Fri, 30 Mar 2012)
@@ -349,5 +349,5 @@
     list_free( saved_var );
     saved_var = L0;
     hashenumerate( module->variables, delete_var_, (void *)0 );
-    hashdone( module->variables );
+    hash_free( module->variables );
 }