Ascertaining the distribution of data pages
Below is an example of an IBEBlock which scans a database file and retrieves some useful information about the distribution of database pages. You can also find this block in the \Blocks\Samples\DB Pages Statistics directory.
execute ibeblock (DBFileName varchar(1000) comment 'Path to database file')
returns (
PageType varchar(100) comment 'Page Type',
PageCount integer comment 'Page Count',
PagePercent numeric(15,2) comment 'Page %',
PageMb numeric(15,2) comment 'Size, Mb')
as
begin
TimeStart = ibec_GetTickCount();
iPageIndex = 0;
aPages = ibec_Array(0,0,0,0,0,0,0,0,0,0,0);
aPageTypes = ibec_Array('Unused', 'Database Header', 'Page Inventory Page', 'Transaction Inventory Page', 'Pointer Page',
'Data Page', 'Index Root Page', 'Index Page', 'Blob Data Page', 'Generator Page', 'Write Ahead Log');
aBitMasks = ibec_Array(1, 2, 4, 8, 16, 32, 64, 128);
fs = ibec_fs_OpenFile(DBFileName, __fmOpenRead + __fmShareDenyNone);
if (fs is null) then
Exit;
try
ibec_fs_Seek(fs, 16, __soFromBeginning);
iPageSize = ibec_fs_ReadWord(fs);
iPageSizeSub20 = iPageSize - 20;
ibec_fs_Seek(fs, iPageSize + 20, __soFromBeginning);
sPIP = ibec_fs_ReadString(fs, iPageSizeSub20);
NextPIPIndex = iPageSizeSub20 * 8 - 1;
ibec_fs_Seek(fs, 0, __soFromBeginning);
while (not ibec_fs_Eof(fs)) do
begin
if (ibec_mod(iPageIndex, 100) = 0) then
begin
TimeSpent = ibec_Div(ibec_GetTickCount() - TimeStart, 1000);
iSpeed = ibec_IIF((iPageIndex = 0) or (TimeSpent = 0), 0, ((iPageSize / 1024) * iPageIndex) / 1024 / TimeSpent);
ibec_Progress(iPageIndex || ' : ' || TimeSpent || ' : ' || iSpeed || ' Mb/s');
end;
iVal = ibec_fs_ReadByte(fs);
iPIPBytePos = ibec_mod(ibec_div(iPageIndex, 8), iPageSizeSub20) + 1;
iPIPBitMaskIdx = ibec_mod(iPageIndex, 8);
if (iPIPBitMaskIdx = 0) then
iPIPByte = ibec_Ord(ibec_Copy(sPIP, iPIPBytePos, 1));
iPIPBitMask = aBitMasks[iPIPBitMaskIdx];
IsUsed = (ibec_and(iPIPBitMask, iPIPByte) = 0);
if (IsUsed) then
aPages[iVal] = aPages[iVal] + 1;
else
aPages[0] = aPages[0] + 1;
if (iPageIndex = NextPIPIndex) then
begin
ibec_fs_Seek(fs, 19, __soFromCurrent);
sPIP = ibec_fs_ReadString(fs, iPageSizeSub20);
NextPIPIndex = NextPIPIndex + iPageSizeSub20 * 8;
end;
iPageIndex = iPageIndex + 1;
ibec_fs_Seek(fs, iPageIndex * iPageSize, __soFromBeginning);
end;
PageType = 'Total Pages';
PageCount = iPageIndex;
PagePercent = 100;
PageMb = (PageCount * (iPageSize / 1024)) / 1024;
suspend;
foreach (aPages as PageCnt key Idx skip nulls) do
begin
PageType = aPageTypes[Idx];
PageCount = PageCnt;
PagePercent = (PageCnt/iPageIndex) * 100;
PageMb = (PageCount * (iPageSize / 1024)) / 1024;
suspend;
end
finally
ibec_fs_CloseFile(fs);
end
end
<< Accessing the input and return parameters when executing in a batch file | IBEBlock | >>







