| 255 | |
| 256 | #define DICT_STATS_VECTLEN 50 |
| 257 | size_t getstats(char *buf, size_t bufsize) const |
| 258 | { |
| 259 | unsigned long i, slots = 0, chainlen, maxchainlen = 0; |
| 260 | unsigned long totchainlen = 0; |
| 261 | unsigned long clvector[DICT_STATS_VECTLEN] = {0}; |
| 262 | size_t l = 0; |
| 263 | |
| 264 | if (empty()) { |
| 265 | return snprintf(buf,bufsize, |
| 266 | "No stats available for empty dictionaries\n"); |
| 267 | } |
| 268 | |
| 269 | /* Compute stats. */ |
| 270 | for (const auto &spvec : m_data) { |
| 271 | if (spvec == nullptr) |
| 272 | continue; |
| 273 | const auto &vec = *spvec; |
| 274 | if (vec.empty()) { |
| 275 | clvector[0]++; |
| 276 | continue; |
| 277 | } |
| 278 | slots++; |
| 279 | /* For each hash entry on this slot... */ |
| 280 | chainlen = vec.size(); |
| 281 | |
| 282 | clvector[(chainlen < DICT_STATS_VECTLEN) ? chainlen : (DICT_STATS_VECTLEN-1)]++; |
| 283 | if (chainlen > maxchainlen) maxchainlen = chainlen; |
| 284 | totchainlen += chainlen; |
| 285 | } |
| 286 | |
| 287 | size_t used = m_data.size()-clvector[0]; |
| 288 | /* Generate human readable stats. */ |
| 289 | l += snprintf(buf+l,bufsize-l, |
| 290 | "semiordered set stats:\n" |
| 291 | " table size: %zu\n" |
| 292 | " number of slots: %zu\n" |
| 293 | " used slots: %ld\n" |
| 294 | " max chain length: %ld\n" |
| 295 | " avg chain length (counted): %.02f\n" |
| 296 | " avg chain length (computed): %.02f\n" |
| 297 | " Chain length distribution:\n", |
| 298 | size(), used, slots, maxchainlen, |
| 299 | (float)totchainlen/slots, (float)size()/m_data.size()); |
| 300 | |
| 301 | for (i = 0; i < DICT_STATS_VECTLEN; i++) { |
| 302 | if (clvector[i] == 0) continue; |
| 303 | if (l >= bufsize) break; |
| 304 | l += snprintf(buf+l,bufsize-l, |
| 305 | " %s%ld: %ld (%.02f%%)\n", |
| 306 | (i == DICT_STATS_VECTLEN-1)?">= ":"", |
| 307 | i, clvector[i], ((float)clvector[i]/m_data.size())*100); |
| 308 | } |
| 309 | |
| 310 | /* Unlike snprintf(), teturn the number of characters actually written. */ |
| 311 | if (bufsize) buf[bufsize-1] = '\0'; |
| 312 | return strlen(buf); |
| 313 | } |
| 314 | |