@@ -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;
@@ -1024,16 +1037,46 @@ int gstat(Firebird::UtilSvc* uSvc)
10241037 // msg 47: " Big record pages: @1
10251038 }
10261039
1027- if (relation->rel_blobs_level_0 || relation->rel_blobs_level_1 || relation->rel_blobs_level_2)
1040+ // Blobs are analyzing only when the record option is set
1041+ if (sw_record)
10281042 {
1029- dba_print(false, 48, SafeArg() << (relation->rel_blobs_level_0 + relation->rel_blobs_level_1 +
1030- relation->rel_blobs_level_2) << relation->rel_blob_space <<
1031- relation->rel_blob_pages);
1032- // msg 48: " Blobs: @1, total length: @2, blob pages: @3
1033-
1034- dba_print(false, 49, SafeArg() << relation->rel_blobs_level_0 << relation->rel_blobs_level_1 <<
1035- relation->rel_blobs_level_2);
1036- // msg 49: " Level 0: @1, Level 1: @2, Level 2: @3
1043+ dba_blob_statistics blobsTotal;
1044+ for (ULONG i = 0; i < MAX_BLOB_LEVELS; ++i)
1045+ {
1046+ blobsTotal += relation->rel_blob_statistics[i];
1047+ }
1048+
1049+ if (blobsTotal.blob_count)
1050+ {
1051+ dba_print(false, 48, SafeArg()
1052+ << blobsTotal.blob_count
1053+ << blobsTotal.blob_space
1054+ << blobsTotal.blob_pages);
1055+ // msg 48: " Blobs: @1, total length: @2, blob pages: @3
1056+
1057+ for (ULONG i = 0; i < MAX_BLOB_LEVELS; ++i)
1058+ {
1059+ const dba_blob_statistics& blob_level = relation->rel_blob_statistics[i];
1060+
1061+ if (blob_level.blob_count > 0)
1062+ {
1063+ dba_print(false, 49, SafeArg()
1064+ << i
1065+ << blob_level.blob_count
1066+ << blob_level.blob_space
1067+ << blob_level.blob_pages);
1068+ // msg 64: " Level @1: @2, total length: @3, blob pages: @4
1069+ }
1070+ }
1071+ }
1072+
1073+
1074+ const FB_SIZE_T tableSize = tddba->page_size * (
1075+ relation->rel_pointer_pages +
1076+ relation->rel_data_pages +
1077+ blobsTotal.blob_pages);
1078+
1079+ dba_print(false, 63, SafeArg() << tableSize); // msg 63: "Table size: @1 bytes
10371080 }
10381081
10391082 dba_print(false, 13); // msg 13: " Fill distribution:"
@@ -1401,32 +1444,31 @@ static bool analyze_data_page( dba_rel* relation, const data_page* page, bool sw
14011444
14021445static void analyze_blob(dba_rel* relation, const blh* blob, int length)
14031446{
1404- relation->rel_blob_space += blob->blh_length;
1405- if (!blob->blh_level)
1406- {
1407- relation->rel_blobs_level_0++;
1408- }
1409- else
1447+ fb_assert(blob->blh_level < MAX_BLOB_LEVELS);
1448+ dba_blob_statistics& blob_level = relation->rel_blob_statistics[blob->blh_level];
1449+
1450+ ++blob_level.blob_count;
1451+ blob_level.blob_space += blob->blh_length;
1452+
1453+ if (blob->blh_level != 0)
14101454 {
14111455 const int slots = (length - BLH_SIZE) / static_cast<int>(sizeof(SLONG));
1412- relation->rel_blob_pages += slots;
1413- if (blob->blh_level == 1)
1414- {
1415- relation->rel_blobs_level_1++;
1416- }
1417- else
1418- {
1419- relation->rel_blobs_level_2++;
1456+ ULONG blobPages = slots;
14201457
1458+ if (blob->blh_level == 2)
1459+ {
14211460 SLONG pages[MAX_PAGE_SIZE / sizeof(SLONG)];
14221461 memcpy(pages, blob->blh_page, slots * sizeof(SLONG));
14231462
14241463 for (int i = 0; i < slots; i++)
14251464 {
14261465 const blob_page* bpage = (const blob_page*) db_read(pages[i]);
1427- relation->rel_blob_pages += bpage->blp_length / sizeof(SLONG);
1466+ blobPages += bpage->blp_length / sizeof(SLONG);
14281467 }
14291468 }
1469+
1470+ relation->rel_blob_pages += blobPages;
1471+ blob_level.blob_pages += blobPages;
14301472 }
14311473}
14321474
0 commit comments