Fossil SCM
Rough prototype for the /artifact_stats page. Still many issues.
Commit
dd1c8fb3ea5a8bebfc37acfa56542e3e21188988cc7797b21fd8bb14e69a2ab6
Parent
561fa8a3b7f2a63…
1 file changed
+87
+87
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -569,5 +569,92 @@ | ||
| 569 | 569 | piechart_render(800,500,PIE_OTHER|PIE_PERCENT); |
| 570 | 570 | @ </svg></center> |
| 571 | 571 | } |
| 572 | 572 | style_footer(); |
| 573 | 573 | } |
| 574 | + | |
| 575 | +/* | |
| 576 | +** Gather statistics on artifact types, counts, and sizes. | |
| 577 | +*/ | |
| 578 | +static void gather_artifact_stats(void){ | |
| 579 | + static const char zSql[] = | |
| 580 | + @ CREATE TEMP TABLE artstat( | |
| 581 | + @ id INTEGER PRIMARY KEY, -- Corresponds to BLOB.RID | |
| 582 | + @ atype TEXT, -- 'data', 'manifest', 'tag', 'wiki', etc. | |
| 583 | + @ isDelta BOOLEAN, -- true if stored as a delta | |
| 584 | + @ szExp, -- expanded, uncompressed size | |
| 585 | + @ szCmpr -- size as stored on disk | |
| 586 | + @ ); | |
| 587 | + @ INSERT INTO artstat(id,atype,isDelta,szExp,szCmpr) | |
| 588 | + @ SELECT blob.rid, | |
| 589 | + @ (SELECT type FROM description WHERE description.rid=blob.rid), | |
| 590 | + @ EXISTS(SELECT 1 FROM delta WHERE delta.rid=blob.rid), | |
| 591 | + @ size, length(content) | |
| 592 | + @ FROM blob WHERE content IS NOT NULL; | |
| 593 | + ; | |
| 594 | + describe_artifacts("IS NOT NULL"); | |
| 595 | + db_multi_exec("%s", zSql/*safe-for-%s*/); | |
| 596 | +} | |
| 597 | + | |
| 598 | +/* | |
| 599 | +** WEBPAGE: artifact_stats | |
| 600 | +** | |
| 601 | +** Show information about the sizes of artifacts in this repository | |
| 602 | +*/ | |
| 603 | +void artifact_stats_page(void){ | |
| 604 | + Stmt q; | |
| 605 | + login_check_credentials(); | |
| 606 | + if( !g.perm.Read ){ login_needed(g.anon.Read); return; } | |
| 607 | + style_header("Artifact Statistics"); | |
| 608 | + gather_artifact_stats(); | |
| 609 | + db_prepare(&q, | |
| 610 | + "SELECT atype, count(*), sum(isDelta), sum(szCmpr), sum(szExp)" | |
| 611 | + " FROM artstat GROUP BY 1" | |
| 612 | + " UNION ALL " | |
| 613 | + "SELECT 'TOTAL', count(*), sum(isDelta), sum(szCmpr), sum(szExp)" | |
| 614 | + " FROM artstat;" | |
| 615 | + ); | |
| 616 | + @ <table class='sortable' border='1'\ | |
| 617 | + @ data-column-types='tkkkkk' data-init-sort='0'> | |
| 618 | + @ <thead><tr> | |
| 619 | + @ <th>Artifact Type</th> | |
| 620 | + @ <th>Count</th> | |
| 621 | + @ <th>Full-Text</th> | |
| 622 | + @ <th>Delta</th> | |
| 623 | + @ <th>Compressed Size</th> | |
| 624 | + @ <th>Uncompressed Size</th> | |
| 625 | + @ </tr></thead><tbody> | |
| 626 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 627 | + const char *zType = db_column_text(&q, 0); | |
| 628 | + int nTotal = db_column_int(&q, 1); | |
| 629 | + int nDelta = db_column_int(&q, 2); | |
| 630 | + int nFull = nTotal - nTotal; | |
| 631 | + sqlite3_int64 szCmpr = db_column_int64(&q, 3); | |
| 632 | + sqlite3_int64 szExp = db_column_int64(&q, 4); | |
| 633 | + char *z; | |
| 634 | + @ <tr><td>%h(zType)</td> | |
| 635 | + | |
| 636 | + z = sqlite3_mprintf("%,d", nTotal); | |
| 637 | + @ <td data-sortkey='%08x(nTotal)' align='right'>%s(z)</td> | |
| 638 | + sqlite3_free(z); | |
| 639 | + | |
| 640 | + z = sqlite3_mprintf("%,d", nDelta); | |
| 641 | + @ <td data-sortkey='%08x(nDelta)' align='right'>%s(z)</td> | |
| 642 | + sqlite3_free(z); | |
| 643 | + | |
| 644 | + z = sqlite3_mprintf("%,d", nFull); | |
| 645 | + @ <td data-sortkey='%08x(nFull)' align='right'>%s(z)</td> | |
| 646 | + sqlite3_free(z); | |
| 647 | + | |
| 648 | + z = sqlite3_mprintf("%,lld", szCmpr); | |
| 649 | + @ <td data-sortkey='%016x(szCmpr)' align='right'>%s(z)</td> | |
| 650 | + sqlite3_free(z); | |
| 651 | + | |
| 652 | + z = sqlite3_mprintf("%,lld", szExp); | |
| 653 | + @ <td data-sortkey='%016x(szExp)' align='right'>%s(z)</td> | |
| 654 | + sqlite3_free(z); | |
| 655 | + } | |
| 656 | + @ </tbody></table></div> | |
| 657 | + db_finalize(&q); | |
| 658 | + style_table_sorter(); | |
| 659 | + style_footer(); | |
| 660 | +} | |
| 574 | 661 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -569,5 +569,92 @@ | |
| 569 | piechart_render(800,500,PIE_OTHER|PIE_PERCENT); |
| 570 | @ </svg></center> |
| 571 | } |
| 572 | style_footer(); |
| 573 | } |
| 574 |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -569,5 +569,92 @@ | |
| 569 | piechart_render(800,500,PIE_OTHER|PIE_PERCENT); |
| 570 | @ </svg></center> |
| 571 | } |
| 572 | style_footer(); |
| 573 | } |
| 574 | |
| 575 | /* |
| 576 | ** Gather statistics on artifact types, counts, and sizes. |
| 577 | */ |
| 578 | static void gather_artifact_stats(void){ |
| 579 | static const char zSql[] = |
| 580 | @ CREATE TEMP TABLE artstat( |
| 581 | @ id INTEGER PRIMARY KEY, -- Corresponds to BLOB.RID |
| 582 | @ atype TEXT, -- 'data', 'manifest', 'tag', 'wiki', etc. |
| 583 | @ isDelta BOOLEAN, -- true if stored as a delta |
| 584 | @ szExp, -- expanded, uncompressed size |
| 585 | @ szCmpr -- size as stored on disk |
| 586 | @ ); |
| 587 | @ INSERT INTO artstat(id,atype,isDelta,szExp,szCmpr) |
| 588 | @ SELECT blob.rid, |
| 589 | @ (SELECT type FROM description WHERE description.rid=blob.rid), |
| 590 | @ EXISTS(SELECT 1 FROM delta WHERE delta.rid=blob.rid), |
| 591 | @ size, length(content) |
| 592 | @ FROM blob WHERE content IS NOT NULL; |
| 593 | ; |
| 594 | describe_artifacts("IS NOT NULL"); |
| 595 | db_multi_exec("%s", zSql/*safe-for-%s*/); |
| 596 | } |
| 597 | |
| 598 | /* |
| 599 | ** WEBPAGE: artifact_stats |
| 600 | ** |
| 601 | ** Show information about the sizes of artifacts in this repository |
| 602 | */ |
| 603 | void artifact_stats_page(void){ |
| 604 | Stmt q; |
| 605 | login_check_credentials(); |
| 606 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 607 | style_header("Artifact Statistics"); |
| 608 | gather_artifact_stats(); |
| 609 | db_prepare(&q, |
| 610 | "SELECT atype, count(*), sum(isDelta), sum(szCmpr), sum(szExp)" |
| 611 | " FROM artstat GROUP BY 1" |
| 612 | " UNION ALL " |
| 613 | "SELECT 'TOTAL', count(*), sum(isDelta), sum(szCmpr), sum(szExp)" |
| 614 | " FROM artstat;" |
| 615 | ); |
| 616 | @ <table class='sortable' border='1'\ |
| 617 | @ data-column-types='tkkkkk' data-init-sort='0'> |
| 618 | @ <thead><tr> |
| 619 | @ <th>Artifact Type</th> |
| 620 | @ <th>Count</th> |
| 621 | @ <th>Full-Text</th> |
| 622 | @ <th>Delta</th> |
| 623 | @ <th>Compressed Size</th> |
| 624 | @ <th>Uncompressed Size</th> |
| 625 | @ </tr></thead><tbody> |
| 626 | while( db_step(&q)==SQLITE_ROW ){ |
| 627 | const char *zType = db_column_text(&q, 0); |
| 628 | int nTotal = db_column_int(&q, 1); |
| 629 | int nDelta = db_column_int(&q, 2); |
| 630 | int nFull = nTotal - nTotal; |
| 631 | sqlite3_int64 szCmpr = db_column_int64(&q, 3); |
| 632 | sqlite3_int64 szExp = db_column_int64(&q, 4); |
| 633 | char *z; |
| 634 | @ <tr><td>%h(zType)</td> |
| 635 | |
| 636 | z = sqlite3_mprintf("%,d", nTotal); |
| 637 | @ <td data-sortkey='%08x(nTotal)' align='right'>%s(z)</td> |
| 638 | sqlite3_free(z); |
| 639 | |
| 640 | z = sqlite3_mprintf("%,d", nDelta); |
| 641 | @ <td data-sortkey='%08x(nDelta)' align='right'>%s(z)</td> |
| 642 | sqlite3_free(z); |
| 643 | |
| 644 | z = sqlite3_mprintf("%,d", nFull); |
| 645 | @ <td data-sortkey='%08x(nFull)' align='right'>%s(z)</td> |
| 646 | sqlite3_free(z); |
| 647 | |
| 648 | z = sqlite3_mprintf("%,lld", szCmpr); |
| 649 | @ <td data-sortkey='%016x(szCmpr)' align='right'>%s(z)</td> |
| 650 | sqlite3_free(z); |
| 651 | |
| 652 | z = sqlite3_mprintf("%,lld", szExp); |
| 653 | @ <td data-sortkey='%016x(szExp)' align='right'>%s(z)</td> |
| 654 | sqlite3_free(z); |
| 655 | } |
| 656 | @ </tbody></table></div> |
| 657 | db_finalize(&q); |
| 658 | style_table_sorter(); |
| 659 | style_footer(); |
| 660 | } |
| 661 |