diff options
Diffstat (limited to 'ot_stats.c')
-rw-r--r-- | ot_stats.c | 63 |
1 files changed, 28 insertions, 35 deletions
@@ -79,7 +79,7 @@ static time_t ot_start_time; | |||
79 | 79 | ||
80 | typedef union stats_network_node stats_network_node; | 80 | typedef union stats_network_node stats_network_node; |
81 | union stats_network_node { | 81 | union 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 { | |||
87 | static stats_network_node *stats_network_counters_root; | 87 | static stats_network_node *stats_network_counters_root; |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | static int stat_increase_network_count( stats_network_node **node, int depth, uintptr_t ip ) { | 90 | static 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 | ||
107 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { | 109 | static 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 | ||
135 | 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 ) { | 129 | 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 ) { |
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; |
278 | success: | 272 | success: |
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 | ||