summaryrefslogtreecommitdiff
path: root/ot_stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_stats.c')
-rw-r--r--ot_stats.c63
1 files 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;
79 79
80typedef union stats_network_node stats_network_node; 80typedef union stats_network_node stats_network_node;
81union stats_network_node { 81union stats_network_node {
82 int counters[STATS_NETWORK_NODE_COUNT]; 82 size_t counters[STATS_NETWORK_NODE_COUNT];
83 stats_network_node *children[STATS_NETWORK_NODE_COUNT]; 83 stats_network_node *children[STATS_NETWORK_NODE_COUNT];
84}; 84};
85 85
@@ -87,63 +87,57 @@ union stats_network_node {
87static stats_network_node *stats_network_counters_root; 87static stats_network_node *stats_network_counters_root;
88#endif 88#endif
89 89
90static int stat_increase_network_count( stats_network_node **node, int depth, uintptr_t ip ) { 90static int stat_increase_network_count( stats_network_node **pnode, int depth, uintptr_t ip ) {
91 int foo = __LDR(ip,depth); 91 int foo = __LDR(ip,depth);
92 92 stats_network_node *node;
93 if( !*node ) { 93
94 *node = malloc( sizeof( stats_network_node ) ); 94 if( !*pnode ) {
95 if( !*node ) 95 *pnode = malloc( sizeof( stats_network_node ) );
96 if( !*pnode )
96 return -1; 97 return -1;
97 memset( *node, 0, sizeof( stats_network_node ) ); 98 memset( *pnode, 0, sizeof( stats_network_node ) );
98 } 99 }
100 node = *pnode;
99 101
100 if( depth < STATS_NETWORK_NODE_MAXDEPTH ) 102 if( depth < STATS_NETWORK_NODE_MAXDEPTH )
101 return stat_increase_network_count( &(*node)->children[ foo ], depth+STATS_NETWORK_NODE_BITWIDTH, ip ); 103 return stat_increase_network_count( node->children + foo, depth+STATS_NETWORK_NODE_BITWIDTH, ip );
102 104
103 (*node)->counters[ foo ]++; 105 node->counters[ foo ]++;
104 return 0; 106 return 0;
105} 107}
106 108
107static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { 109static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) {
108 int i, rest = 0; 110 int i, rest = 0;
109 if( !*node ) return 0;
110
111 depth += STATS_NETWORK_NODE_BITWIDTH;
112 if( depth == STATS_NETWORK_NODE_MAXDEPTH ) {
113 for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i )
114 rest += (*node)->counters[i] >>= shift;
115 return rest;
116 }
117
118 for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) {
119 stats_network_node **childnode = &(*node)->children[i];
120 int rest_val;
121
122 if( !*childnode ) continue;
123 111
124 rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); 112 if( !*node )
113 return 0;
125 114
126 if( rest_val ) continue; 115 for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i )
116 if( depth < STATS_NETWORK_NODE_MAXDEPTH )
117 rest += stats_shift_down_network_count( (*node)->children + i, depth+STATS_NETWORK_NODE_BITWIDTH, shift );
118 else
119 rest += (*node)->counters[i] >>= shift;
127 120
128 free( (*node)->children[i] ); 121 if( !rest ) {
129 (*node)->children[i] = NULL; 122 free( *node );
123 *node = NULL;
130 } 124 }
131 125
132 return rest; 126 return rest;
133} 127}
134 128
135static 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 ) { 129static 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 ) {
136 size_t score = 0; 130 size_t score = 0;
137 int i; 131 int i;
138 malloc(100); 132
139 if( !node ) return 0; 133 if( !node ) return 0;
140 134
141 if( depth < limit ) { 135 if( depth < limit ) {
142 for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) 136 for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i )
143 if( node->children[i] ) { 137 if( node->children[i] ) {
144 __STR(node_value,depth,i); 138 __STR(node_value,depth,i);
145 score += stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit ); 139 score += stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit );
146 } 140 }
147 return score; 141 return score;
148 } 142 }
149 143
@@ -277,8 +271,7 @@ bailout_error:
277 r = reply; 271 r = reply;
278success: 272success:
279 stats_shift_down_network_count( &slash24s_network_counters_root, 0, sizeof(int)*8-1 ); 273 stats_shift_down_network_count( &slash24s_network_counters_root, 0, sizeof(int)*8-1 );
280 if( slash24s_network_counters_root ) 274
281 free( slash24s_network_counters_root );
282 return r-reply; 275 return r-reply;
283} 276}
284 277