Fossil SCM
Add the "," qualifier to %d formats in printf() and use the capability for improve display of stats.
Commit
2cdbdbb1c9b7ad2b7b7cf4d23844227dc104d0d5a1f672b820b96541d7766d9b
Parent
71e777dd730fa9a…
2 files changed
+19
-2
+49
-75
+19
-2
| --- src/printf.c | ||
| +++ src/printf.c | ||
| @@ -275,10 +275,11 @@ | ||
| 275 | 275 | etByte flag_altform2; /* True if "!" flag is present */ |
| 276 | 276 | etByte flag_zeropad; /* True if field width constant starts with zero */ |
| 277 | 277 | etByte flag_long; /* True if "l" flag is present */ |
| 278 | 278 | etByte flag_longlong; /* True if the "ll" flag is present */ |
| 279 | 279 | etByte done; /* Loop termination flag */ |
| 280 | + etByte cThousand; /* Thousands separator for %d and %u */ | |
| 280 | 281 | u64 longvalue; /* Value for integer types */ |
| 281 | 282 | long double realvalue; /* Value for real types */ |
| 282 | 283 | const et_info *infop; /* Pointer to the appropriate info structure */ |
| 283 | 284 | char buf[etBUFSIZE]; /* Conversion buffer */ |
| 284 | 285 | char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ |
| @@ -312,11 +313,11 @@ | ||
| 312 | 313 | blob_append(pBlob,"%",1); |
| 313 | 314 | count++; |
| 314 | 315 | break; |
| 315 | 316 | } |
| 316 | 317 | /* Find out what flags are present */ |
| 317 | - flag_leftjustify = flag_plussign = flag_blanksign = | |
| 318 | + flag_leftjustify = flag_plussign = flag_blanksign = cThousand = | |
| 318 | 319 | flag_alternateform = flag_altform2 = flag_zeropad = 0; |
| 319 | 320 | done = 0; |
| 320 | 321 | do{ |
| 321 | 322 | switch( c ){ |
| 322 | 323 | case '-': flag_leftjustify = 1; break; |
| @@ -323,10 +324,11 @@ | ||
| 323 | 324 | case '+': flag_plussign = 1; break; |
| 324 | 325 | case ' ': flag_blanksign = 1; break; |
| 325 | 326 | case '#': flag_alternateform = 1; break; |
| 326 | 327 | case '!': flag_altform2 = 1; break; |
| 327 | 328 | case '0': flag_zeropad = 1; break; |
| 329 | + case ',': cThousand = ','; break; | |
| 328 | 330 | default: done = 1; break; |
| 329 | 331 | } |
| 330 | 332 | }while( !done && (c=(*++fmt))!=0 ); |
| 331 | 333 | /* Get the field width */ |
| 332 | 334 | width = 0; |
| @@ -454,12 +456,27 @@ | ||
| 454 | 456 | *(--bufpt) = cset[longvalue%base]; |
| 455 | 457 | longvalue = longvalue/base; |
| 456 | 458 | }while( longvalue>0 ); |
| 457 | 459 | } |
| 458 | 460 | length = &buf[etBUFSIZE-1]-bufpt; |
| 459 | - for(idx=precision-length; idx>0; idx--){ | |
| 461 | + while( precision>length ){ | |
| 460 | 462 | *(--bufpt) = '0'; /* Zero pad */ |
| 463 | + length++; | |
| 464 | + } | |
| 465 | + if( cThousand ){ | |
| 466 | + int nn = (length - 1)/3; /* Number of "," to insert */ | |
| 467 | + int ix = (length - 1)%3 + 1; | |
| 468 | + bufpt -= nn; | |
| 469 | + for(idx=0; nn>0; idx++){ | |
| 470 | + bufpt[idx] = bufpt[idx+nn]; | |
| 471 | + ix--; | |
| 472 | + if( ix==0 ){ | |
| 473 | + bufpt[++idx] = cThousand; | |
| 474 | + nn--; | |
| 475 | + ix = 3; | |
| 476 | + } | |
| 477 | + } | |
| 461 | 478 | } |
| 462 | 479 | if( prefix ) *(--bufpt) = prefix; /* Add sign */ |
| 463 | 480 | if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ |
| 464 | 481 | const char *pre; |
| 465 | 482 | char x; |
| 466 | 483 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -275,10 +275,11 @@ | |
| 275 | etByte flag_altform2; /* True if "!" flag is present */ |
| 276 | etByte flag_zeropad; /* True if field width constant starts with zero */ |
| 277 | etByte flag_long; /* True if "l" flag is present */ |
| 278 | etByte flag_longlong; /* True if the "ll" flag is present */ |
| 279 | etByte done; /* Loop termination flag */ |
| 280 | u64 longvalue; /* Value for integer types */ |
| 281 | long double realvalue; /* Value for real types */ |
| 282 | const et_info *infop; /* Pointer to the appropriate info structure */ |
| 283 | char buf[etBUFSIZE]; /* Conversion buffer */ |
| 284 | char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ |
| @@ -312,11 +313,11 @@ | |
| 312 | blob_append(pBlob,"%",1); |
| 313 | count++; |
| 314 | break; |
| 315 | } |
| 316 | /* Find out what flags are present */ |
| 317 | flag_leftjustify = flag_plussign = flag_blanksign = |
| 318 | flag_alternateform = flag_altform2 = flag_zeropad = 0; |
| 319 | done = 0; |
| 320 | do{ |
| 321 | switch( c ){ |
| 322 | case '-': flag_leftjustify = 1; break; |
| @@ -323,10 +324,11 @@ | |
| 323 | case '+': flag_plussign = 1; break; |
| 324 | case ' ': flag_blanksign = 1; break; |
| 325 | case '#': flag_alternateform = 1; break; |
| 326 | case '!': flag_altform2 = 1; break; |
| 327 | case '0': flag_zeropad = 1; break; |
| 328 | default: done = 1; break; |
| 329 | } |
| 330 | }while( !done && (c=(*++fmt))!=0 ); |
| 331 | /* Get the field width */ |
| 332 | width = 0; |
| @@ -454,12 +456,27 @@ | |
| 454 | *(--bufpt) = cset[longvalue%base]; |
| 455 | longvalue = longvalue/base; |
| 456 | }while( longvalue>0 ); |
| 457 | } |
| 458 | length = &buf[etBUFSIZE-1]-bufpt; |
| 459 | for(idx=precision-length; idx>0; idx--){ |
| 460 | *(--bufpt) = '0'; /* Zero pad */ |
| 461 | } |
| 462 | if( prefix ) *(--bufpt) = prefix; /* Add sign */ |
| 463 | if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ |
| 464 | const char *pre; |
| 465 | char x; |
| 466 |
| --- src/printf.c | |
| +++ src/printf.c | |
| @@ -275,10 +275,11 @@ | |
| 275 | etByte flag_altform2; /* True if "!" flag is present */ |
| 276 | etByte flag_zeropad; /* True if field width constant starts with zero */ |
| 277 | etByte flag_long; /* True if "l" flag is present */ |
| 278 | etByte flag_longlong; /* True if the "ll" flag is present */ |
| 279 | etByte done; /* Loop termination flag */ |
| 280 | etByte cThousand; /* Thousands separator for %d and %u */ |
| 281 | u64 longvalue; /* Value for integer types */ |
| 282 | long double realvalue; /* Value for real types */ |
| 283 | const et_info *infop; /* Pointer to the appropriate info structure */ |
| 284 | char buf[etBUFSIZE]; /* Conversion buffer */ |
| 285 | char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ |
| @@ -312,11 +313,11 @@ | |
| 313 | blob_append(pBlob,"%",1); |
| 314 | count++; |
| 315 | break; |
| 316 | } |
| 317 | /* Find out what flags are present */ |
| 318 | flag_leftjustify = flag_plussign = flag_blanksign = cThousand = |
| 319 | flag_alternateform = flag_altform2 = flag_zeropad = 0; |
| 320 | done = 0; |
| 321 | do{ |
| 322 | switch( c ){ |
| 323 | case '-': flag_leftjustify = 1; break; |
| @@ -323,10 +324,11 @@ | |
| 324 | case '+': flag_plussign = 1; break; |
| 325 | case ' ': flag_blanksign = 1; break; |
| 326 | case '#': flag_alternateform = 1; break; |
| 327 | case '!': flag_altform2 = 1; break; |
| 328 | case '0': flag_zeropad = 1; break; |
| 329 | case ',': cThousand = ','; break; |
| 330 | default: done = 1; break; |
| 331 | } |
| 332 | }while( !done && (c=(*++fmt))!=0 ); |
| 333 | /* Get the field width */ |
| 334 | width = 0; |
| @@ -454,12 +456,27 @@ | |
| 456 | *(--bufpt) = cset[longvalue%base]; |
| 457 | longvalue = longvalue/base; |
| 458 | }while( longvalue>0 ); |
| 459 | } |
| 460 | length = &buf[etBUFSIZE-1]-bufpt; |
| 461 | while( precision>length ){ |
| 462 | *(--bufpt) = '0'; /* Zero pad */ |
| 463 | length++; |
| 464 | } |
| 465 | if( cThousand ){ |
| 466 | int nn = (length - 1)/3; /* Number of "," to insert */ |
| 467 | int ix = (length - 1)%3 + 1; |
| 468 | bufpt -= nn; |
| 469 | for(idx=0; nn>0; idx++){ |
| 470 | bufpt[idx] = bufpt[idx+nn]; |
| 471 | ix--; |
| 472 | if( ix==0 ){ |
| 473 | bufpt[++idx] = cThousand; |
| 474 | nn--; |
| 475 | ix = 3; |
| 476 | } |
| 477 | } |
| 478 | } |
| 479 | if( prefix ) *(--bufpt) = prefix; /* Add sign */ |
| 480 | if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ |
| 481 | const char *pre; |
| 482 | char x; |
| 483 |
+49
-75
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -27,26 +27,26 @@ | ||
| 27 | 27 | ** For a sufficiently large integer, provide an alternative |
| 28 | 28 | ** representation as MB or GB or TB. |
| 29 | 29 | */ |
| 30 | 30 | void bigSizeName(int nOut, char *zOut, sqlite3_int64 v){ |
| 31 | 31 | if( v<100000 ){ |
| 32 | - sqlite3_snprintf(nOut, zOut, "%lld bytes", v); | |
| 32 | + sqlite3_snprintf(nOut, zOut, "%,lld bytes", v); | |
| 33 | 33 | }else if( v<1000000000 ){ |
| 34 | - sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fMB)", | |
| 34 | + sqlite3_snprintf(nOut, zOut, "%,lld bytes (%.1fMB)", | |
| 35 | 35 | v, (double)v/1000000.0); |
| 36 | 36 | }else{ |
| 37 | - sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fGB)", | |
| 37 | + sqlite3_snprintf(nOut, zOut, "%,lld bytes (%.1fGB)", | |
| 38 | 38 | v, (double)v/1000000000.0); |
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | /* |
| 43 | 43 | ** Return the approximate size as KB, MB, GB, or TB. |
| 44 | 44 | */ |
| 45 | 45 | void approxSizeName(int nOut, char *zOut, sqlite3_int64 v){ |
| 46 | 46 | if( v<1000 ){ |
| 47 | - sqlite3_snprintf(nOut, zOut, "%lld bytes", v); | |
| 47 | + sqlite3_snprintf(nOut, zOut, "%,lld bytes", v); | |
| 48 | 48 | }else if( v<1000000 ){ |
| 49 | 49 | sqlite3_snprintf(nOut, zOut, "%.1fKB", (double)v/1000.0); |
| 50 | 50 | }else if( v<1000000000 ){ |
| 51 | 51 | sqlite3_snprintf(nOut, zOut, "%.1fMB", (double)v/1000000.0); |
| 52 | 52 | }else{ |
| @@ -85,20 +85,18 @@ | ||
| 85 | 85 | } |
| 86 | 86 | if( g.perm.Admin || g.perm.Setup || db_get_boolean("test_env_enable",0) ){ |
| 87 | 87 | style_submenu_element("Environment", "test_env"); |
| 88 | 88 | } |
| 89 | 89 | @ <table class="label-value"> |
| 90 | - @ <tr><th>Repository Size:</th><td> | |
| 91 | 90 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 92 | - bigSizeName(sizeof(zBuf), zBuf, fsize); | |
| 93 | - @ %s(zBuf) | |
| 91 | + @ <tr><th>Repository Size:</th><td>%,lld(fsize) bytes</td> | |
| 94 | 92 | @ </td></tr> |
| 95 | 93 | if( !brief ){ |
| 96 | 94 | @ <tr><th>Number Of Artifacts:</th><td> |
| 97 | 95 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 98 | 96 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 99 | - @ %d(n) (%d(n-m) fulltext and %d(m) deltas) | |
| 97 | + @ %.d(n) (%,d(n-m) fulltext and %,d(m) deltas) | |
| 100 | 98 | if( g.perm.Write ){ |
| 101 | 99 | @ <a href='%R/artifact_stats'>Details</a> |
| 102 | 100 | } |
| 103 | 101 | @ </td></tr> |
| 104 | 102 | if( n>0 ){ |
| @@ -110,12 +108,11 @@ | ||
| 110 | 108 | db_step(&q); |
| 111 | 109 | t = db_column_int64(&q, 0); |
| 112 | 110 | szAvg = db_column_int(&q, 1); |
| 113 | 111 | szMax = db_column_int(&q, 2); |
| 114 | 112 | db_finalize(&q); |
| 115 | - bigSizeName(sizeof(zBuf), zBuf, t); | |
| 116 | - @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) total | |
| 113 | + @ %,d(szAvg) bytes average, %,d(szMax) bytes max, %,lld(t) total | |
| 117 | 114 | @ </td></tr> |
| 118 | 115 | @ <tr><th>Compression Ratio:</th><td> |
| 119 | 116 | if( t/fsize < 5 ){ |
| 120 | 117 | b = 10; |
| 121 | 118 | a = t/(fsize/10); |
| @@ -146,31 +143,31 @@ | ||
| 146 | 143 | } |
| 147 | 144 | db_finalize(&q); |
| 148 | 145 | } |
| 149 | 146 | @ <tr><th>Number Of Check-ins:</th><td> |
| 150 | 147 | n = db_int(0, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"); |
| 151 | - @ %d(n) | |
| 148 | + @ %,d(n) | |
| 152 | 149 | @ </td></tr> |
| 153 | 150 | @ <tr><th>Number Of Files:</th><td> |
| 154 | 151 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 155 | - @ %d(n) | |
| 152 | + @ %,d(n) | |
| 156 | 153 | @ </td></tr> |
| 157 | 154 | @ <tr><th>Number Of Wiki Pages:</th><td> |
| 158 | 155 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 159 | 156 | " WHERE +tagname GLOB 'wiki-*'"); |
| 160 | - @ %d(n) | |
| 157 | + @ %,d(n) | |
| 161 | 158 | @ </td></tr> |
| 162 | 159 | @ <tr><th>Number Of Tickets:</th><td> |
| 163 | 160 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 164 | 161 | " WHERE +tagname GLOB 'tkt-*'"); |
| 165 | - @ %d(n) | |
| 162 | + @ %,d(n) | |
| 166 | 163 | @ </td></tr> |
| 167 | 164 | } |
| 168 | 165 | @ <tr><th>Duration Of Project:</th><td> |
| 169 | 166 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 170 | 167 | " + 0.99"); |
| 171 | - @ %d(n) days or approximately %.2f(n/365.2425) years. | |
| 168 | + @ %,d(n) days or approximately %.2f(n/365.2425) years. | |
| 172 | 169 | @ </td></tr> |
| 173 | 170 | p = db_get("project-code", 0); |
| 174 | 171 | if( p ){ |
| 175 | 172 | @ <tr><th>Project ID:</th> |
| 176 | 173 | @ <td>%h(p) %h(db_get("project-name",""))</td></tr> |
| @@ -196,13 +193,13 @@ | ||
| 196 | 193 | } |
| 197 | 194 | @ <tr><th>Repository Rebuilt:</th><td> |
| 198 | 195 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 199 | 196 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 200 | 197 | @ <tr><th>Database Stats:</th><td> |
| 201 | - @ %d(db_int(0, "PRAGMA repository.page_count")) pages, | |
| 198 | + @ %,d(db_int(0, "PRAGMA repository.page_count")) pages, | |
| 202 | 199 | @ %d(db_int(0, "PRAGMA repository.page_size")) bytes/page, |
| 203 | - @ %d(db_int(0, "PRAGMA repository.freelist_count")) free pages, | |
| 200 | + @ %,d(db_int(0, "PRAGMA repository.freelist_count")) free pages, | |
| 204 | 201 | @ %s(db_text(0, "PRAGMA repository.encoding")), |
| 205 | 202 | @ %s(db_text(0, "PRAGMA repository.journal_mode")) mode |
| 206 | 203 | @ </td></tr> |
| 207 | 204 | |
| 208 | 205 | @ </table> |
| @@ -245,16 +242,15 @@ | ||
| 245 | 242 | || (z = db_get("short-project-name",0))!=0 |
| 246 | 243 | ){ |
| 247 | 244 | fossil_print("%*s%s\n", colWidth, "project-name:", z); |
| 248 | 245 | } |
| 249 | 246 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 250 | - bigSizeName(sizeof(zBuf), zBuf, fsize); | |
| 251 | - fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); | |
| 247 | + fossil_print( "%*s%,lld bytes\n", colWidth, "repository-size:", fsize); | |
| 252 | 248 | if( !brief ){ |
| 253 | 249 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 254 | 250 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 255 | - fossil_print("%*s%d (stored as %d full text and %d delta blobs)\n", | |
| 251 | + fossil_print("%*s%,d (stored as %,d full text and %,d deltas)\n", | |
| 256 | 252 | colWidth, "artifact-count:", |
| 257 | 253 | n, n-m, m); |
| 258 | 254 | if( n>0 ){ |
| 259 | 255 | int a, b; |
| 260 | 256 | Stmt q; |
| @@ -263,15 +259,14 @@ | ||
| 263 | 259 | db_step(&q); |
| 264 | 260 | t = db_column_int64(&q, 0); |
| 265 | 261 | szAvg = db_column_int(&q, 1); |
| 266 | 262 | szMax = db_column_int(&q, 2); |
| 267 | 263 | db_finalize(&q); |
| 268 | - bigSizeName(sizeof(zBuf), zBuf, t); | |
| 269 | - fossil_print( "%*s%d average, " | |
| 270 | - "%d max, %s total\n", | |
| 264 | + fossil_print( "%*s%,d average, " | |
| 265 | + "%,d max, %,lld total\n", | |
| 271 | 266 | colWidth, "artifact-sizes:", |
| 272 | - szAvg, szMax, zBuf); | |
| 267 | + szAvg, szMax, t); | |
| 273 | 268 | if( t/fsize < 5 ){ |
| 274 | 269 | b = 10; |
| 275 | 270 | fsize /= 10; |
| 276 | 271 | }else{ |
| 277 | 272 | b = 1; |
| @@ -278,34 +273,34 @@ | ||
| 278 | 273 | } |
| 279 | 274 | a = t/fsize; |
| 280 | 275 | fossil_print("%*s%d:%d\n", colWidth, "compression-ratio:", a, b); |
| 281 | 276 | } |
| 282 | 277 | n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'"); |
| 283 | - fossil_print("%*s%d\n", colWidth, "check-ins:", n); | |
| 278 | + fossil_print("%*s%,d\n", colWidth, "check-ins:", n); | |
| 284 | 279 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 285 | - fossil_print("%*s%d across all branches\n", colWidth, "files:", n); | |
| 280 | + fossil_print("%*s%,d across all branches\n", colWidth, "files:", n); | |
| 286 | 281 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 287 | 282 | " WHERE tagname GLOB 'wiki-*'"); |
| 288 | 283 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'"); |
| 289 | - fossil_print("%*s%d (%d changes)\n", colWidth, "wiki-pages:", n, m); | |
| 284 | + fossil_print("%*s%,d (%,d changes)\n", colWidth, "wiki-pages:", n, m); | |
| 290 | 285 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 291 | 286 | " WHERE tagname GLOB 'tkt-*'"); |
| 292 | 287 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'"); |
| 293 | - fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); | |
| 288 | + fossil_print("%*s%,d (%,d changes)\n", colWidth, "tickets:", n, m); | |
| 294 | 289 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 295 | - fossil_print("%*s%d\n", colWidth, "events:", n); | |
| 290 | + fossil_print("%*s%,d\n", colWidth, "events:", n); | |
| 296 | 291 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 297 | - fossil_print("%*s%d\n", colWidth, "tag-changes:", n); | |
| 292 | + fossil_print("%*s%,d\n", colWidth, "tag-changes:", n); | |
| 298 | 293 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 299 | 294 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 300 | 295 | " || ' days ago' FROM event " |
| 301 | 296 | " ORDER BY mtime DESC LIMIT 1"); |
| 302 | 297 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 303 | 298 | } |
| 304 | 299 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 305 | 300 | " + 0.99"); |
| 306 | - fossil_print("%*s%d days or approximately %.2f years.\n", | |
| 301 | + fossil_print("%*s%,d days or approximately %.2f years.\n", | |
| 307 | 302 | colWidth, "project-age:", n, n/365.2425); |
| 308 | 303 | p = db_get("project-code", 0); |
| 309 | 304 | if( p ){ |
| 310 | 305 | fossil_print("%*s%s\n", colWidth, "project-id:", p); |
| 311 | 306 | } |
| @@ -322,11 +317,11 @@ | ||
| 322 | 317 | fossil_print("%*s%.19s [%.10s] (%s)\n", |
| 323 | 318 | colWidth, "sqlite-version:", |
| 324 | 319 | sqlite3_sourceid(), &sqlite3_sourceid()[20], |
| 325 | 320 | sqlite3_libversion()); |
| 326 | 321 | } |
| 327 | - fossil_print("%*s%d pages, %d bytes/pg, %d free pages, " | |
| 322 | + fossil_print("%*s%,d pages, %d bytes/pg, %,d free pages, " | |
| 328 | 323 | "%s, %s mode\n", |
| 329 | 324 | colWidth, "database-stats:", |
| 330 | 325 | db_int(0, "PRAGMA repository.page_count"), |
| 331 | 326 | db_int(0, "PRAGMA repository.page_size"), |
| 332 | 327 | db_int(0, "PRAGMA repository.freelist_count"), |
| @@ -644,11 +639,11 @@ | ||
| 644 | 639 | ** Output text "the largest N artifacts". Make this text a hyperlink |
| 645 | 640 | ** to bigbloblist if N is not too big. |
| 646 | 641 | */ |
| 647 | 642 | static void largest_n_artifacts(int N){ |
| 648 | 643 | if( N>250 ){ |
| 649 | - @ (the largest %d(N) artifacts) | |
| 644 | + @ (the largest %,d(N) artifacts) | |
| 650 | 645 | }else{ |
| 651 | 646 | @ (the <a href='%R/bigbloblist?n=%d(N)'>largest %d(N) artifacts</a>) |
| 652 | 647 | } |
| 653 | 648 | } |
| 654 | 649 | |
| @@ -731,47 +726,41 @@ | ||
| 731 | 726 | } |
| 732 | 727 | db_finalize(&q); |
| 733 | 728 | |
| 734 | 729 | @ <h1>Overall Artifact Size Statistics:</h1> |
| 735 | 730 | @ <table class="label-value"> |
| 736 | - @ <tr><th>Number of artifacts:</th><td>%d(nTotal)</td></tr> | |
| 731 | + @ <tr><th>Number of artifacts:</th><td>%,d(nTotal)</td></tr> | |
| 737 | 732 | @ <tr><th>Number of deltas:</th>\ |
| 738 | - @ <td>%d(nDelta) (%d(nDelta*100/nTotal)%%)</td></tr> | |
| 739 | - @ <tr><th>Number of full-text:</th><td>%d(nFull) \ | |
| 733 | + @ <td>%,d(nDelta) (%d(nDelta*100/nTotal)%%)</td></tr> | |
| 734 | + @ <tr><th>Number of full-text:</th><td>%,d(nFull) \ | |
| 740 | 735 | @ (%d(nFull*100/nTotal)%%)</td></tr> |
| 741 | - @ <tr><th>Largest compressed artifact size:</th>\ | |
| 742 | - @ <td>%d(mxCmpr)</td></tr> | |
| 743 | - @ <tr><th>Average compressed artifact size:</th> \ | |
| 744 | - @ <td>%.2f(avgCmpr)</td></tr> | |
| 745 | - @ <tr><th>Median compressed artifact size:</th><td>%d(medCmpr)</td></tr> | |
| 746 | - @ <tr><th>Largest uncompressed artifact size:</td>\ | |
| 747 | - @ <td>%d(mxExp)</td></tr> | |
| 748 | - @ <tr><th>Average uncompressed artifact size:</th> \ | |
| 749 | - @ <td>%.2f(avgExp)</td></tr> | |
| 750 | 736 | medExp = db_int(0, "SELECT szExp FROM artstat ORDER BY szExp" |
| 751 | 737 | " LIMIT 1 OFFSET %d", nTotal/2); |
| 752 | - @ <tr><th>Median uncompressed artifact size:</th><td>%d(medExp)</td></tr> | |
| 738 | + @ <tr><th>Uncompressed artifact sizes:</th>\ | |
| 739 | + @ <td>largest: %,d(mxExp), average: %,d((int)avgExp), median: %,d(medExp)</td> | |
| 740 | + @ <tr><th>Compressed artifact sizes:</th>\ | |
| 741 | + @ <td>largest: %,d(mxCmpr), average: %,d((int)avgCmpr), \ | |
| 742 | + @ median: %,d(medCmpr)</td> | |
| 743 | + | |
| 753 | 744 | db_prepare(&q, |
| 754 | 745 | "SELECT avg(szCmpr), max(szCmpr) FROM artstat WHERE isDelta" |
| 755 | 746 | ); |
| 756 | 747 | if( db_step(&q)==SQLITE_ROW ){ |
| 757 | - @ <tr><th>Largest delta:</td>\ | |
| 758 | - @ <td>%d(db_column_int(&q,1))</td></tr> | |
| 759 | - | |
| 760 | - @ <tr><th>Average delta:</th> \ | |
| 761 | - @ <td>%.2f(db_column_double(&q,0))</td></tr> | |
| 762 | - | |
| 748 | + int mxDelta = db_column_int(&q,1); | |
| 749 | + double avgDelta = db_column_double(&q,0); | |
| 763 | 750 | med = db_int(0, "SELECT szCmpr FROM artstat WHERE isDelta ORDER BY szCmpr" |
| 764 | 751 | " LIMIT 1 OFFSET %d", nDelta/2); |
| 765 | - @ <tr><th>Median delta:</th><td>%d(med)</td></tr> | |
| 752 | + @ <tr><th>Delta artifact sizes:</th>\ | |
| 753 | + @ <td>largest: %,d(mxDelta), average: %,d((int)avgDelta), \ | |
| 754 | + @ median: %,d(med)</td> | |
| 766 | 755 | } |
| 767 | 756 | db_finalize(&q); |
| 768 | 757 | r = db_double(0.0, "SELECT avg(szCmpr) FROM artstat WHERE NOT isDelta;"); |
| 769 | - @ <tr><th>Average full-text artifact:</th><td>%.2f(r)</td></tr> | |
| 770 | 758 | med = db_int(0, "SELECT szCmpr FROM artstat WHERE NOT isDelta ORDER BY szCmpr" |
| 771 | 759 | " LIMIT 1 OFFSET %d", nFull/2); |
| 772 | - @ <tr><th>Median full-text artifact:</th><td>%d(med)</td></tr> | |
| 760 | + @ <tr><th>Full-text artifact sizes:</th> | |
| 761 | + @ <td>largest: %,d(mxCmpr), average: %,d((int)r), median: %,d(med)</td> | |
| 773 | 762 | @ </table> |
| 774 | 763 | |
| 775 | 764 | @ <h1>Artifact size distribution facts:</h1> |
| 776 | 765 | @ <ol> |
| 777 | 766 | @ <li><p>The largest %.2f(n50pct*100.0/nTotal)%% of artifacts |
| @@ -817,30 +806,15 @@ | ||
| 817 | 806 | int nFull = nTotal - nDelta; |
| 818 | 807 | sqlite3_int64 szCmpr = db_column_int64(&q, 3); |
| 819 | 808 | sqlite3_int64 szExp = db_column_int64(&q, 4); |
| 820 | 809 | char *z; |
| 821 | 810 | @ <tr><td>%h(zType)</td> |
| 822 | - | |
| 823 | - z = sqlite3_mprintf("%,d", nTotal); | |
| 824 | - @ <td data-sortkey='%08x(nTotal)' align='right'>%s(z)</td> | |
| 825 | - sqlite3_free(z); | |
| 826 | - | |
| 827 | - z = sqlite3_mprintf("%,d", nFull); | |
| 828 | - @ <td data-sortkey='%08x(nFull)' align='right'>%s(z)</td> | |
| 829 | - sqlite3_free(z); | |
| 830 | - | |
| 831 | - z = sqlite3_mprintf("%,d", nDelta); | |
| 832 | - @ <td data-sortkey='%08x(nDelta)' align='right'>%s(z)</td> | |
| 833 | - sqlite3_free(z); | |
| 834 | - | |
| 835 | - z = sqlite3_mprintf("%,lld", szCmpr); | |
| 836 | - @ <td data-sortkey='%016x(szCmpr)' align='right'>%s(z)</td> | |
| 837 | - sqlite3_free(z); | |
| 838 | - | |
| 839 | - z = sqlite3_mprintf("%,lld", szExp); | |
| 840 | - @ <td data-sortkey='%016x(szExp)' align='right'>%s(z)</td> | |
| 841 | - sqlite3_free(z); | |
| 811 | + @ <td data-sortkey='%08x(nTotal)' align='right'>%,d(nTotal)</td> | |
| 812 | + @ <td data-sortkey='%08x(nFull)' align='right'>%,d(nFull)</td> | |
| 813 | + @ <td data-sortkey='%08x(nDelta)' align='right'>%,d(nDelta)</td> | |
| 814 | + @ <td data-sortkey='%016x(szCmpr)' align='right'>%,lld(szCmpr)</td> | |
| 815 | + @ <td data-sortkey='%016x(szExp)' align='right'>%,lld(szExp)</td> | |
| 842 | 816 | } |
| 843 | 817 | @ </tbody></table> |
| 844 | 818 | db_finalize(&q); |
| 845 | 819 | |
| 846 | 820 | if( db_exists("SELECT 1 FROM artstat WHERE atype='unused'") ){ |
| 847 | 821 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -27,26 +27,26 @@ | |
| 27 | ** For a sufficiently large integer, provide an alternative |
| 28 | ** representation as MB or GB or TB. |
| 29 | */ |
| 30 | void bigSizeName(int nOut, char *zOut, sqlite3_int64 v){ |
| 31 | if( v<100000 ){ |
| 32 | sqlite3_snprintf(nOut, zOut, "%lld bytes", v); |
| 33 | }else if( v<1000000000 ){ |
| 34 | sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fMB)", |
| 35 | v, (double)v/1000000.0); |
| 36 | }else{ |
| 37 | sqlite3_snprintf(nOut, zOut, "%lld bytes (%.1fGB)", |
| 38 | v, (double)v/1000000000.0); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** Return the approximate size as KB, MB, GB, or TB. |
| 44 | */ |
| 45 | void approxSizeName(int nOut, char *zOut, sqlite3_int64 v){ |
| 46 | if( v<1000 ){ |
| 47 | sqlite3_snprintf(nOut, zOut, "%lld bytes", v); |
| 48 | }else if( v<1000000 ){ |
| 49 | sqlite3_snprintf(nOut, zOut, "%.1fKB", (double)v/1000.0); |
| 50 | }else if( v<1000000000 ){ |
| 51 | sqlite3_snprintf(nOut, zOut, "%.1fMB", (double)v/1000000.0); |
| 52 | }else{ |
| @@ -85,20 +85,18 @@ | |
| 85 | } |
| 86 | if( g.perm.Admin || g.perm.Setup || db_get_boolean("test_env_enable",0) ){ |
| 87 | style_submenu_element("Environment", "test_env"); |
| 88 | } |
| 89 | @ <table class="label-value"> |
| 90 | @ <tr><th>Repository Size:</th><td> |
| 91 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 92 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 93 | @ %s(zBuf) |
| 94 | @ </td></tr> |
| 95 | if( !brief ){ |
| 96 | @ <tr><th>Number Of Artifacts:</th><td> |
| 97 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 98 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 99 | @ %d(n) (%d(n-m) fulltext and %d(m) deltas) |
| 100 | if( g.perm.Write ){ |
| 101 | @ <a href='%R/artifact_stats'>Details</a> |
| 102 | } |
| 103 | @ </td></tr> |
| 104 | if( n>0 ){ |
| @@ -110,12 +108,11 @@ | |
| 110 | db_step(&q); |
| 111 | t = db_column_int64(&q, 0); |
| 112 | szAvg = db_column_int(&q, 1); |
| 113 | szMax = db_column_int(&q, 2); |
| 114 | db_finalize(&q); |
| 115 | bigSizeName(sizeof(zBuf), zBuf, t); |
| 116 | @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) total |
| 117 | @ </td></tr> |
| 118 | @ <tr><th>Compression Ratio:</th><td> |
| 119 | if( t/fsize < 5 ){ |
| 120 | b = 10; |
| 121 | a = t/(fsize/10); |
| @@ -146,31 +143,31 @@ | |
| 146 | } |
| 147 | db_finalize(&q); |
| 148 | } |
| 149 | @ <tr><th>Number Of Check-ins:</th><td> |
| 150 | n = db_int(0, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"); |
| 151 | @ %d(n) |
| 152 | @ </td></tr> |
| 153 | @ <tr><th>Number Of Files:</th><td> |
| 154 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 155 | @ %d(n) |
| 156 | @ </td></tr> |
| 157 | @ <tr><th>Number Of Wiki Pages:</th><td> |
| 158 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 159 | " WHERE +tagname GLOB 'wiki-*'"); |
| 160 | @ %d(n) |
| 161 | @ </td></tr> |
| 162 | @ <tr><th>Number Of Tickets:</th><td> |
| 163 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 164 | " WHERE +tagname GLOB 'tkt-*'"); |
| 165 | @ %d(n) |
| 166 | @ </td></tr> |
| 167 | } |
| 168 | @ <tr><th>Duration Of Project:</th><td> |
| 169 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 170 | " + 0.99"); |
| 171 | @ %d(n) days or approximately %.2f(n/365.2425) years. |
| 172 | @ </td></tr> |
| 173 | p = db_get("project-code", 0); |
| 174 | if( p ){ |
| 175 | @ <tr><th>Project ID:</th> |
| 176 | @ <td>%h(p) %h(db_get("project-name",""))</td></tr> |
| @@ -196,13 +193,13 @@ | |
| 196 | } |
| 197 | @ <tr><th>Repository Rebuilt:</th><td> |
| 198 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 199 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 200 | @ <tr><th>Database Stats:</th><td> |
| 201 | @ %d(db_int(0, "PRAGMA repository.page_count")) pages, |
| 202 | @ %d(db_int(0, "PRAGMA repository.page_size")) bytes/page, |
| 203 | @ %d(db_int(0, "PRAGMA repository.freelist_count")) free pages, |
| 204 | @ %s(db_text(0, "PRAGMA repository.encoding")), |
| 205 | @ %s(db_text(0, "PRAGMA repository.journal_mode")) mode |
| 206 | @ </td></tr> |
| 207 | |
| 208 | @ </table> |
| @@ -245,16 +242,15 @@ | |
| 245 | || (z = db_get("short-project-name",0))!=0 |
| 246 | ){ |
| 247 | fossil_print("%*s%s\n", colWidth, "project-name:", z); |
| 248 | } |
| 249 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 250 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 251 | fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf ); |
| 252 | if( !brief ){ |
| 253 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 254 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 255 | fossil_print("%*s%d (stored as %d full text and %d delta blobs)\n", |
| 256 | colWidth, "artifact-count:", |
| 257 | n, n-m, m); |
| 258 | if( n>0 ){ |
| 259 | int a, b; |
| 260 | Stmt q; |
| @@ -263,15 +259,14 @@ | |
| 263 | db_step(&q); |
| 264 | t = db_column_int64(&q, 0); |
| 265 | szAvg = db_column_int(&q, 1); |
| 266 | szMax = db_column_int(&q, 2); |
| 267 | db_finalize(&q); |
| 268 | bigSizeName(sizeof(zBuf), zBuf, t); |
| 269 | fossil_print( "%*s%d average, " |
| 270 | "%d max, %s total\n", |
| 271 | colWidth, "artifact-sizes:", |
| 272 | szAvg, szMax, zBuf); |
| 273 | if( t/fsize < 5 ){ |
| 274 | b = 10; |
| 275 | fsize /= 10; |
| 276 | }else{ |
| 277 | b = 1; |
| @@ -278,34 +273,34 @@ | |
| 278 | } |
| 279 | a = t/fsize; |
| 280 | fossil_print("%*s%d:%d\n", colWidth, "compression-ratio:", a, b); |
| 281 | } |
| 282 | n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'"); |
| 283 | fossil_print("%*s%d\n", colWidth, "check-ins:", n); |
| 284 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 285 | fossil_print("%*s%d across all branches\n", colWidth, "files:", n); |
| 286 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 287 | " WHERE tagname GLOB 'wiki-*'"); |
| 288 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'"); |
| 289 | fossil_print("%*s%d (%d changes)\n", colWidth, "wiki-pages:", n, m); |
| 290 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 291 | " WHERE tagname GLOB 'tkt-*'"); |
| 292 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'"); |
| 293 | fossil_print("%*s%d (%d changes)\n", colWidth, "tickets:", n, m); |
| 294 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 295 | fossil_print("%*s%d\n", colWidth, "events:", n); |
| 296 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 297 | fossil_print("%*s%d\n", colWidth, "tag-changes:", n); |
| 298 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 299 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 300 | " || ' days ago' FROM event " |
| 301 | " ORDER BY mtime DESC LIMIT 1"); |
| 302 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 303 | } |
| 304 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 305 | " + 0.99"); |
| 306 | fossil_print("%*s%d days or approximately %.2f years.\n", |
| 307 | colWidth, "project-age:", n, n/365.2425); |
| 308 | p = db_get("project-code", 0); |
| 309 | if( p ){ |
| 310 | fossil_print("%*s%s\n", colWidth, "project-id:", p); |
| 311 | } |
| @@ -322,11 +317,11 @@ | |
| 322 | fossil_print("%*s%.19s [%.10s] (%s)\n", |
| 323 | colWidth, "sqlite-version:", |
| 324 | sqlite3_sourceid(), &sqlite3_sourceid()[20], |
| 325 | sqlite3_libversion()); |
| 326 | } |
| 327 | fossil_print("%*s%d pages, %d bytes/pg, %d free pages, " |
| 328 | "%s, %s mode\n", |
| 329 | colWidth, "database-stats:", |
| 330 | db_int(0, "PRAGMA repository.page_count"), |
| 331 | db_int(0, "PRAGMA repository.page_size"), |
| 332 | db_int(0, "PRAGMA repository.freelist_count"), |
| @@ -644,11 +639,11 @@ | |
| 644 | ** Output text "the largest N artifacts". Make this text a hyperlink |
| 645 | ** to bigbloblist if N is not too big. |
| 646 | */ |
| 647 | static void largest_n_artifacts(int N){ |
| 648 | if( N>250 ){ |
| 649 | @ (the largest %d(N) artifacts) |
| 650 | }else{ |
| 651 | @ (the <a href='%R/bigbloblist?n=%d(N)'>largest %d(N) artifacts</a>) |
| 652 | } |
| 653 | } |
| 654 | |
| @@ -731,47 +726,41 @@ | |
| 731 | } |
| 732 | db_finalize(&q); |
| 733 | |
| 734 | @ <h1>Overall Artifact Size Statistics:</h1> |
| 735 | @ <table class="label-value"> |
| 736 | @ <tr><th>Number of artifacts:</th><td>%d(nTotal)</td></tr> |
| 737 | @ <tr><th>Number of deltas:</th>\ |
| 738 | @ <td>%d(nDelta) (%d(nDelta*100/nTotal)%%)</td></tr> |
| 739 | @ <tr><th>Number of full-text:</th><td>%d(nFull) \ |
| 740 | @ (%d(nFull*100/nTotal)%%)</td></tr> |
| 741 | @ <tr><th>Largest compressed artifact size:</th>\ |
| 742 | @ <td>%d(mxCmpr)</td></tr> |
| 743 | @ <tr><th>Average compressed artifact size:</th> \ |
| 744 | @ <td>%.2f(avgCmpr)</td></tr> |
| 745 | @ <tr><th>Median compressed artifact size:</th><td>%d(medCmpr)</td></tr> |
| 746 | @ <tr><th>Largest uncompressed artifact size:</td>\ |
| 747 | @ <td>%d(mxExp)</td></tr> |
| 748 | @ <tr><th>Average uncompressed artifact size:</th> \ |
| 749 | @ <td>%.2f(avgExp)</td></tr> |
| 750 | medExp = db_int(0, "SELECT szExp FROM artstat ORDER BY szExp" |
| 751 | " LIMIT 1 OFFSET %d", nTotal/2); |
| 752 | @ <tr><th>Median uncompressed artifact size:</th><td>%d(medExp)</td></tr> |
| 753 | db_prepare(&q, |
| 754 | "SELECT avg(szCmpr), max(szCmpr) FROM artstat WHERE isDelta" |
| 755 | ); |
| 756 | if( db_step(&q)==SQLITE_ROW ){ |
| 757 | @ <tr><th>Largest delta:</td>\ |
| 758 | @ <td>%d(db_column_int(&q,1))</td></tr> |
| 759 | |
| 760 | @ <tr><th>Average delta:</th> \ |
| 761 | @ <td>%.2f(db_column_double(&q,0))</td></tr> |
| 762 | |
| 763 | med = db_int(0, "SELECT szCmpr FROM artstat WHERE isDelta ORDER BY szCmpr" |
| 764 | " LIMIT 1 OFFSET %d", nDelta/2); |
| 765 | @ <tr><th>Median delta:</th><td>%d(med)</td></tr> |
| 766 | } |
| 767 | db_finalize(&q); |
| 768 | r = db_double(0.0, "SELECT avg(szCmpr) FROM artstat WHERE NOT isDelta;"); |
| 769 | @ <tr><th>Average full-text artifact:</th><td>%.2f(r)</td></tr> |
| 770 | med = db_int(0, "SELECT szCmpr FROM artstat WHERE NOT isDelta ORDER BY szCmpr" |
| 771 | " LIMIT 1 OFFSET %d", nFull/2); |
| 772 | @ <tr><th>Median full-text artifact:</th><td>%d(med)</td></tr> |
| 773 | @ </table> |
| 774 | |
| 775 | @ <h1>Artifact size distribution facts:</h1> |
| 776 | @ <ol> |
| 777 | @ <li><p>The largest %.2f(n50pct*100.0/nTotal)%% of artifacts |
| @@ -817,30 +806,15 @@ | |
| 817 | int nFull = nTotal - nDelta; |
| 818 | sqlite3_int64 szCmpr = db_column_int64(&q, 3); |
| 819 | sqlite3_int64 szExp = db_column_int64(&q, 4); |
| 820 | char *z; |
| 821 | @ <tr><td>%h(zType)</td> |
| 822 | |
| 823 | z = sqlite3_mprintf("%,d", nTotal); |
| 824 | @ <td data-sortkey='%08x(nTotal)' align='right'>%s(z)</td> |
| 825 | sqlite3_free(z); |
| 826 | |
| 827 | z = sqlite3_mprintf("%,d", nFull); |
| 828 | @ <td data-sortkey='%08x(nFull)' align='right'>%s(z)</td> |
| 829 | sqlite3_free(z); |
| 830 | |
| 831 | z = sqlite3_mprintf("%,d", nDelta); |
| 832 | @ <td data-sortkey='%08x(nDelta)' align='right'>%s(z)</td> |
| 833 | sqlite3_free(z); |
| 834 | |
| 835 | z = sqlite3_mprintf("%,lld", szCmpr); |
| 836 | @ <td data-sortkey='%016x(szCmpr)' align='right'>%s(z)</td> |
| 837 | sqlite3_free(z); |
| 838 | |
| 839 | z = sqlite3_mprintf("%,lld", szExp); |
| 840 | @ <td data-sortkey='%016x(szExp)' align='right'>%s(z)</td> |
| 841 | sqlite3_free(z); |
| 842 | } |
| 843 | @ </tbody></table> |
| 844 | db_finalize(&q); |
| 845 | |
| 846 | if( db_exists("SELECT 1 FROM artstat WHERE atype='unused'") ){ |
| 847 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -27,26 +27,26 @@ | |
| 27 | ** For a sufficiently large integer, provide an alternative |
| 28 | ** representation as MB or GB or TB. |
| 29 | */ |
| 30 | void bigSizeName(int nOut, char *zOut, sqlite3_int64 v){ |
| 31 | if( v<100000 ){ |
| 32 | sqlite3_snprintf(nOut, zOut, "%,lld bytes", v); |
| 33 | }else if( v<1000000000 ){ |
| 34 | sqlite3_snprintf(nOut, zOut, "%,lld bytes (%.1fMB)", |
| 35 | v, (double)v/1000000.0); |
| 36 | }else{ |
| 37 | sqlite3_snprintf(nOut, zOut, "%,lld bytes (%.1fGB)", |
| 38 | v, (double)v/1000000000.0); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | /* |
| 43 | ** Return the approximate size as KB, MB, GB, or TB. |
| 44 | */ |
| 45 | void approxSizeName(int nOut, char *zOut, sqlite3_int64 v){ |
| 46 | if( v<1000 ){ |
| 47 | sqlite3_snprintf(nOut, zOut, "%,lld bytes", v); |
| 48 | }else if( v<1000000 ){ |
| 49 | sqlite3_snprintf(nOut, zOut, "%.1fKB", (double)v/1000.0); |
| 50 | }else if( v<1000000000 ){ |
| 51 | sqlite3_snprintf(nOut, zOut, "%.1fMB", (double)v/1000000.0); |
| 52 | }else{ |
| @@ -85,20 +85,18 @@ | |
| 85 | } |
| 86 | if( g.perm.Admin || g.perm.Setup || db_get_boolean("test_env_enable",0) ){ |
| 87 | style_submenu_element("Environment", "test_env"); |
| 88 | } |
| 89 | @ <table class="label-value"> |
| 90 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 91 | @ <tr><th>Repository Size:</th><td>%,lld(fsize) bytes</td> |
| 92 | @ </td></tr> |
| 93 | if( !brief ){ |
| 94 | @ <tr><th>Number Of Artifacts:</th><td> |
| 95 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 96 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 97 | @ %.d(n) (%,d(n-m) fulltext and %,d(m) deltas) |
| 98 | if( g.perm.Write ){ |
| 99 | @ <a href='%R/artifact_stats'>Details</a> |
| 100 | } |
| 101 | @ </td></tr> |
| 102 | if( n>0 ){ |
| @@ -110,12 +108,11 @@ | |
| 108 | db_step(&q); |
| 109 | t = db_column_int64(&q, 0); |
| 110 | szAvg = db_column_int(&q, 1); |
| 111 | szMax = db_column_int(&q, 2); |
| 112 | db_finalize(&q); |
| 113 | @ %,d(szAvg) bytes average, %,d(szMax) bytes max, %,lld(t) total |
| 114 | @ </td></tr> |
| 115 | @ <tr><th>Compression Ratio:</th><td> |
| 116 | if( t/fsize < 5 ){ |
| 117 | b = 10; |
| 118 | a = t/(fsize/10); |
| @@ -146,31 +143,31 @@ | |
| 143 | } |
| 144 | db_finalize(&q); |
| 145 | } |
| 146 | @ <tr><th>Number Of Check-ins:</th><td> |
| 147 | n = db_int(0, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"); |
| 148 | @ %,d(n) |
| 149 | @ </td></tr> |
| 150 | @ <tr><th>Number Of Files:</th><td> |
| 151 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 152 | @ %,d(n) |
| 153 | @ </td></tr> |
| 154 | @ <tr><th>Number Of Wiki Pages:</th><td> |
| 155 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 156 | " WHERE +tagname GLOB 'wiki-*'"); |
| 157 | @ %,d(n) |
| 158 | @ </td></tr> |
| 159 | @ <tr><th>Number Of Tickets:</th><td> |
| 160 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 161 | " WHERE +tagname GLOB 'tkt-*'"); |
| 162 | @ %,d(n) |
| 163 | @ </td></tr> |
| 164 | } |
| 165 | @ <tr><th>Duration Of Project:</th><td> |
| 166 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 167 | " + 0.99"); |
| 168 | @ %,d(n) days or approximately %.2f(n/365.2425) years. |
| 169 | @ </td></tr> |
| 170 | p = db_get("project-code", 0); |
| 171 | if( p ){ |
| 172 | @ <tr><th>Project ID:</th> |
| 173 | @ <td>%h(p) %h(db_get("project-name",""))</td></tr> |
| @@ -196,13 +193,13 @@ | |
| 193 | } |
| 194 | @ <tr><th>Repository Rebuilt:</th><td> |
| 195 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 196 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 197 | @ <tr><th>Database Stats:</th><td> |
| 198 | @ %,d(db_int(0, "PRAGMA repository.page_count")) pages, |
| 199 | @ %d(db_int(0, "PRAGMA repository.page_size")) bytes/page, |
| 200 | @ %,d(db_int(0, "PRAGMA repository.freelist_count")) free pages, |
| 201 | @ %s(db_text(0, "PRAGMA repository.encoding")), |
| 202 | @ %s(db_text(0, "PRAGMA repository.journal_mode")) mode |
| 203 | @ </td></tr> |
| 204 | |
| 205 | @ </table> |
| @@ -245,16 +242,15 @@ | |
| 242 | || (z = db_get("short-project-name",0))!=0 |
| 243 | ){ |
| 244 | fossil_print("%*s%s\n", colWidth, "project-name:", z); |
| 245 | } |
| 246 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 247 | fossil_print( "%*s%,lld bytes\n", colWidth, "repository-size:", fsize); |
| 248 | if( !brief ){ |
| 249 | n = db_int(0, "SELECT count(*) FROM blob"); |
| 250 | m = db_int(0, "SELECT count(*) FROM delta"); |
| 251 | fossil_print("%*s%,d (stored as %,d full text and %,d deltas)\n", |
| 252 | colWidth, "artifact-count:", |
| 253 | n, n-m, m); |
| 254 | if( n>0 ){ |
| 255 | int a, b; |
| 256 | Stmt q; |
| @@ -263,15 +259,14 @@ | |
| 259 | db_step(&q); |
| 260 | t = db_column_int64(&q, 0); |
| 261 | szAvg = db_column_int(&q, 1); |
| 262 | szMax = db_column_int(&q, 2); |
| 263 | db_finalize(&q); |
| 264 | fossil_print( "%*s%,d average, " |
| 265 | "%,d max, %,lld total\n", |
| 266 | colWidth, "artifact-sizes:", |
| 267 | szAvg, szMax, t); |
| 268 | if( t/fsize < 5 ){ |
| 269 | b = 10; |
| 270 | fsize /= 10; |
| 271 | }else{ |
| 272 | b = 1; |
| @@ -278,34 +273,34 @@ | |
| 273 | } |
| 274 | a = t/fsize; |
| 275 | fossil_print("%*s%d:%d\n", colWidth, "compression-ratio:", a, b); |
| 276 | } |
| 277 | n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'"); |
| 278 | fossil_print("%*s%,d\n", colWidth, "check-ins:", n); |
| 279 | n = db_int(0, "SELECT count(*) FROM filename /*scan*/"); |
| 280 | fossil_print("%*s%,d across all branches\n", colWidth, "files:", n); |
| 281 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 282 | " WHERE tagname GLOB 'wiki-*'"); |
| 283 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'"); |
| 284 | fossil_print("%*s%,d (%,d changes)\n", colWidth, "wiki-pages:", n, m); |
| 285 | n = db_int(0, "SELECT count(*) FROM tag /*scan*/" |
| 286 | " WHERE tagname GLOB 'tkt-*'"); |
| 287 | m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'"); |
| 288 | fossil_print("%*s%,d (%,d changes)\n", colWidth, "tickets:", n, m); |
| 289 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'"); |
| 290 | fossil_print("%*s%,d\n", colWidth, "events:", n); |
| 291 | n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'"); |
| 292 | fossil_print("%*s%,d\n", colWidth, "tag-changes:", n); |
| 293 | z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||" |
| 294 | " CAST(julianday('now') - mtime AS INTEGER)" |
| 295 | " || ' days ago' FROM event " |
| 296 | " ORDER BY mtime DESC LIMIT 1"); |
| 297 | fossil_print("%*s%s\n", colWidth, "latest-change:", z); |
| 298 | } |
| 299 | n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)" |
| 300 | " + 0.99"); |
| 301 | fossil_print("%*s%,d days or approximately %.2f years.\n", |
| 302 | colWidth, "project-age:", n, n/365.2425); |
| 303 | p = db_get("project-code", 0); |
| 304 | if( p ){ |
| 305 | fossil_print("%*s%s\n", colWidth, "project-id:", p); |
| 306 | } |
| @@ -322,11 +317,11 @@ | |
| 317 | fossil_print("%*s%.19s [%.10s] (%s)\n", |
| 318 | colWidth, "sqlite-version:", |
| 319 | sqlite3_sourceid(), &sqlite3_sourceid()[20], |
| 320 | sqlite3_libversion()); |
| 321 | } |
| 322 | fossil_print("%*s%,d pages, %d bytes/pg, %,d free pages, " |
| 323 | "%s, %s mode\n", |
| 324 | colWidth, "database-stats:", |
| 325 | db_int(0, "PRAGMA repository.page_count"), |
| 326 | db_int(0, "PRAGMA repository.page_size"), |
| 327 | db_int(0, "PRAGMA repository.freelist_count"), |
| @@ -644,11 +639,11 @@ | |
| 639 | ** Output text "the largest N artifacts". Make this text a hyperlink |
| 640 | ** to bigbloblist if N is not too big. |
| 641 | */ |
| 642 | static void largest_n_artifacts(int N){ |
| 643 | if( N>250 ){ |
| 644 | @ (the largest %,d(N) artifacts) |
| 645 | }else{ |
| 646 | @ (the <a href='%R/bigbloblist?n=%d(N)'>largest %d(N) artifacts</a>) |
| 647 | } |
| 648 | } |
| 649 | |
| @@ -731,47 +726,41 @@ | |
| 726 | } |
| 727 | db_finalize(&q); |
| 728 | |
| 729 | @ <h1>Overall Artifact Size Statistics:</h1> |
| 730 | @ <table class="label-value"> |
| 731 | @ <tr><th>Number of artifacts:</th><td>%,d(nTotal)</td></tr> |
| 732 | @ <tr><th>Number of deltas:</th>\ |
| 733 | @ <td>%,d(nDelta) (%d(nDelta*100/nTotal)%%)</td></tr> |
| 734 | @ <tr><th>Number of full-text:</th><td>%,d(nFull) \ |
| 735 | @ (%d(nFull*100/nTotal)%%)</td></tr> |
| 736 | medExp = db_int(0, "SELECT szExp FROM artstat ORDER BY szExp" |
| 737 | " LIMIT 1 OFFSET %d", nTotal/2); |
| 738 | @ <tr><th>Uncompressed artifact sizes:</th>\ |
| 739 | @ <td>largest: %,d(mxExp), average: %,d((int)avgExp), median: %,d(medExp)</td> |
| 740 | @ <tr><th>Compressed artifact sizes:</th>\ |
| 741 | @ <td>largest: %,d(mxCmpr), average: %,d((int)avgCmpr), \ |
| 742 | @ median: %,d(medCmpr)</td> |
| 743 | |
| 744 | db_prepare(&q, |
| 745 | "SELECT avg(szCmpr), max(szCmpr) FROM artstat WHERE isDelta" |
| 746 | ); |
| 747 | if( db_step(&q)==SQLITE_ROW ){ |
| 748 | int mxDelta = db_column_int(&q,1); |
| 749 | double avgDelta = db_column_double(&q,0); |
| 750 | med = db_int(0, "SELECT szCmpr FROM artstat WHERE isDelta ORDER BY szCmpr" |
| 751 | " LIMIT 1 OFFSET %d", nDelta/2); |
| 752 | @ <tr><th>Delta artifact sizes:</th>\ |
| 753 | @ <td>largest: %,d(mxDelta), average: %,d((int)avgDelta), \ |
| 754 | @ median: %,d(med)</td> |
| 755 | } |
| 756 | db_finalize(&q); |
| 757 | r = db_double(0.0, "SELECT avg(szCmpr) FROM artstat WHERE NOT isDelta;"); |
| 758 | med = db_int(0, "SELECT szCmpr FROM artstat WHERE NOT isDelta ORDER BY szCmpr" |
| 759 | " LIMIT 1 OFFSET %d", nFull/2); |
| 760 | @ <tr><th>Full-text artifact sizes:</th> |
| 761 | @ <td>largest: %,d(mxCmpr), average: %,d((int)r), median: %,d(med)</td> |
| 762 | @ </table> |
| 763 | |
| 764 | @ <h1>Artifact size distribution facts:</h1> |
| 765 | @ <ol> |
| 766 | @ <li><p>The largest %.2f(n50pct*100.0/nTotal)%% of artifacts |
| @@ -817,30 +806,15 @@ | |
| 806 | int nFull = nTotal - nDelta; |
| 807 | sqlite3_int64 szCmpr = db_column_int64(&q, 3); |
| 808 | sqlite3_int64 szExp = db_column_int64(&q, 4); |
| 809 | char *z; |
| 810 | @ <tr><td>%h(zType)</td> |
| 811 | @ <td data-sortkey='%08x(nTotal)' align='right'>%,d(nTotal)</td> |
| 812 | @ <td data-sortkey='%08x(nFull)' align='right'>%,d(nFull)</td> |
| 813 | @ <td data-sortkey='%08x(nDelta)' align='right'>%,d(nDelta)</td> |
| 814 | @ <td data-sortkey='%016x(szCmpr)' align='right'>%,lld(szCmpr)</td> |
| 815 | @ <td data-sortkey='%016x(szExp)' align='right'>%,lld(szExp)</td> |
| 816 | } |
| 817 | @ </tbody></table> |
| 818 | db_finalize(&q); |
| 819 | |
| 820 | if( db_exists("SELECT 1 FROM artstat WHERE atype='unused'") ){ |
| 821 |