From 6eeb16123c4fa147b464aca99fc910b5aa02d36f Mon Sep 17 00:00:00 2001
From: erdgeist <>
Date: Tue, 1 Sep 2009 23:45:37 +0000
Subject: Cleanup s24s code, remove an ugly mem leak, thanks to Vasya P. for
 pointing at the bug and suggesting a fix

---
 ot_stats.c | 63 ++++++++++++++++++++++++++++----------------------------------
 1 file changed, 28 insertions(+), 35 deletions(-)

diff --git a/ot_stats.c b/ot_stats.c
index c452475..8e6a0c9 100644
--- a/ot_stats.c
+++ b/ot_stats.c
@@ -79,7 +79,7 @@ static time_t ot_start_time;
 
 typedef union stats_network_node stats_network_node;
 union stats_network_node {
-  int                 counters[STATS_NETWORK_NODE_COUNT];
+  size_t              counters[STATS_NETWORK_NODE_COUNT];
   stats_network_node *children[STATS_NETWORK_NODE_COUNT];
 };
 
@@ -87,63 +87,57 @@ union stats_network_node {
 static stats_network_node *stats_network_counters_root;
 #endif
 
-static int stat_increase_network_count( stats_network_node **node, int depth, uintptr_t ip ) {
+static int stat_increase_network_count( stats_network_node **pnode, int depth, uintptr_t ip ) {
   int foo = __LDR(ip,depth);
-
-  if( !*node ) {
-    *node = malloc( sizeof( stats_network_node ) );
-    if( !*node )
+  stats_network_node *node;
+  
+  if( !*pnode ) {
+    *pnode = malloc( sizeof( stats_network_node ) );
+    if( !*pnode )
       return -1;
-    memset( *node, 0, sizeof( stats_network_node ) );
+    memset( *pnode, 0, sizeof( stats_network_node ) );
   }
+  node = *pnode;
 
   if( depth < STATS_NETWORK_NODE_MAXDEPTH )
-    return stat_increase_network_count( &(*node)->children[ foo ], depth+STATS_NETWORK_NODE_BITWIDTH, ip );
+    return stat_increase_network_count( node->children + foo, depth+STATS_NETWORK_NODE_BITWIDTH, ip );
 
-  (*node)->counters[ foo ]++;
+  node->counters[ foo ]++;
   return 0;
 }
 
 static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) {
   int i, rest = 0;
-  if( !*node ) return 0;
-
-  depth += STATS_NETWORK_NODE_BITWIDTH;
-  if( depth == STATS_NETWORK_NODE_MAXDEPTH ) {
-    for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i )
-      rest += (*node)->counters[i] >>= shift;
-    return rest;
-  }
-
-  for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) {
-    stats_network_node **childnode = &(*node)->children[i];
-    int rest_val;
-
-    if( !*childnode ) continue;
 
-    rest += rest_val = stats_shift_down_network_count( childnode, depth, shift );
+  if( !*node )
+    return 0;
 
-    if( rest_val ) continue;
+  for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i )
+    if( depth < STATS_NETWORK_NODE_MAXDEPTH )
+      rest += stats_shift_down_network_count( (*node)->children + i, depth+STATS_NETWORK_NODE_BITWIDTH, shift );
+    else
+      rest += (*node)->counters[i] >>= shift;
 
-    free( (*node)->children[i] );
-    (*node)->children[i] = NULL;
+  if( !rest ) {
+    free( *node );
+    *node = NULL;
   }
-
+  
   return rest;
 }
 
 static size_t stats_get_highscore_networks( stats_network_node *node, int depth, ot_ip6 node_value, size_t *scores, ot_ip6 *networks, int network_count, int limit ) {
   size_t score = 0;
   int i;
-  malloc(100);
+
   if( !node ) return 0;
 
   if( depth < limit ) {
     for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i )
-    if( node->children[i] ) {
-      __STR(node_value,depth,i);
-      score += stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit );
-    }
+      if( node->children[i] ) {
+        __STR(node_value,depth,i);
+        score += stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit );
+      }
     return score;
   }
 
@@ -277,8 +271,7 @@ bailout_error:
   r = reply;
 success:
   stats_shift_down_network_count( &slash24s_network_counters_root, 0, sizeof(int)*8-1 );
-  if( slash24s_network_counters_root )
-    free( slash24s_network_counters_root );
+
   return r-reply;
 }
 
-- 
cgit v1.2.3