@@ -123,6 +123,22 @@ struct dba_fmt
123123 bool fmt_used;
124124};
125125
126+ inline constexpr ULONG MAX_BLOB_LEVELS = 3;
127+ struct dba_blob_statistics
128+ {
129+ FB_UINT64 blob_count = 0;
130+ FB_UINT64 blob_space = 0;
131+ FB_UINT64 blob_pages = 0;
132+
133+ dba_blob_statistics& operator+=(const dba_blob_statistics& rhs)
134+ {
135+ blob_count += rhs.blob_count;
136+ blob_space += rhs.blob_space;
137+ blob_pages += rhs.blob_pages;
138+ return *this;
139+ }
140+ };
141+
126142struct dba_rel
127143{
128144 dba_rel* rel_next;
@@ -147,10 +163,7 @@ struct dba_rel
147163 FB_UINT64 rel_fragments;
148164 FB_UINT64 rel_fragment_space;
149165 FB_UINT64 rel_max_fragments;
150- FB_UINT64 rel_blobs_level_0;
151- FB_UINT64 rel_blobs_level_1;
152- FB_UINT64 rel_blobs_level_2;
153- FB_UINT64 rel_blob_space;
166+ dba_blob_statistics rel_blob_statistics[MAX_BLOB_LEVELS];
154167 ULONG rel_fill_distribution[BUCKETS];
155168 FB_UINT64 rel_format_space;
156169 FB_UINT64 rel_total_space;
@@ -1082,16 +1095,46 @@ int gstat(Firebird::UtilSvc* uSvc)
10821095 // msg 47: " Big record pages: @1
10831096 }
10841097
1085- if (relation->rel_blobs_level_0 || relation->rel_blobs_level_1 || relation->rel_blobs_level_2)
1098+ // Blobs are analyzing only when the record option is set
1099+ if (sw_record)
10861100 {
1087- dba_print(false, 48, SafeArg() << (relation->rel_blobs_level_0 + relation->rel_blobs_level_1 +
1088- relation->rel_blobs_level_2) << relation->rel_blob_space <<
1089- relation->rel_blob_pages);
1090- // msg 48: " Blobs: @1, total length: @2, blob pages: @3
1091-
1092- dba_print(false, 49, SafeArg() << relation->rel_blobs_level_0 << relation->rel_blobs_level_1 <<
1093- relation->rel_blobs_level_2);
1094- // msg 49: " Level 0: @1, Level 1: @2, Level 2: @3
1101+ dba_blob_statistics blobsTotal;
1102+ for (ULONG i = 0; i < MAX_BLOB_LEVELS; ++i)
1103+ {
1104+ blobsTotal += relation->rel_blob_statistics[i];
1105+ }
1106+
1107+ if (blobsTotal.blob_count)
1108+ {
1109+ dba_print(false, 48, SafeArg()
1110+ << blobsTotal.blob_count
1111+ << blobsTotal.blob_space
1112+ << blobsTotal.blob_pages);
1113+ // msg 48: " Blobs: @1, total length: @2, blob pages: @3
1114+
1115+ for (ULONG i = 0; i < MAX_BLOB_LEVELS; ++i)
1116+ {
1117+ const dba_blob_statistics& blob_level = relation->rel_blob_statistics[i];
1118+
1119+ if (blob_level.blob_count > 0)
1120+ {
1121+ dba_print(false, 49, SafeArg()
1122+ << i
1123+ << blob_level.blob_count
1124+ << blob_level.blob_space
1125+ << blob_level.blob_pages);
1126+ // msg 64: " Level @1: @2, total length: @3, blob pages: @4
1127+ }
1128+ }
1129+ }
1130+
1131+
1132+ const FB_SIZE_T tableSize = tddba->page_size * (
1133+ relation->rel_pointer_pages +
1134+ relation->rel_data_pages +
1135+ blobsTotal.blob_pages);
1136+
1137+ dba_print(false, 63, SafeArg() << tableSize); // msg 63: "Table size: @1 bytes
10951138 }
10961139
10971140 dba_print(false, 13); // msg 13: " Fill distribution:"
@@ -1470,32 +1513,31 @@ static bool analyze_data_page( dba_rel* relation, const data_page* page, bool sw
14701513
14711514static void analyze_blob(dba_rel* relation, const blh* blob, int length)
14721515{
1473- relation->rel_blob_space += blob->blh_length;
1474- if (!blob->blh_level)
1475- {
1476- relation->rel_blobs_level_0++;
1477- }
1478- else
1516+ fb_assert(blob->blh_level < MAX_BLOB_LEVELS);
1517+ dba_blob_statistics& blob_level = relation->rel_blob_statistics[blob->blh_level];
1518+
1519+ ++blob_level.blob_count;
1520+ blob_level.blob_space += blob->blh_length;
1521+
1522+ if (blob->blh_level != 0)
14791523 {
14801524 const int slots = (length - BLH_SIZE) / static_cast<int>(sizeof(SLONG));
1481- relation->rel_blob_pages += slots;
1482- if (blob->blh_level == 1)
1483- {
1484- relation->rel_blobs_level_1++;
1485- }
1486- else
1487- {
1488- relation->rel_blobs_level_2++;
1525+ ULONG blobPages = slots;
14891526
1527+ if (blob->blh_level == 2)
1528+ {
14901529 SLONG pages[MAX_PAGE_SIZE / sizeof(SLONG)];
14911530 memcpy(pages, blob->blh_page, slots * sizeof(SLONG));
14921531
14931532 for (int i = 0; i < slots; i++)
14941533 {
14951534 const blob_page* bpage = (const blob_page*) db_read(pages[i]);
1496- relation->rel_blob_pages += bpage->blp_length / sizeof(SLONG);
1535+ blobPages += bpage->blp_length / sizeof(SLONG);
14971536 }
14981537 }
1538+
1539+ relation->rel_blob_pages += blobPages;
1540+ blob_level.blob_pages += blobPages;
14991541 }
15001542}
15011543
0 commit comments