52704.fb2
OldValue : longint;
OldInx : integer;
NewInx : integer;
NewBucketNum : longint;
StartDirEntry : longint;
NewStartDirEntry : longint;
EndDirEntry : longint;
begin
FindInfo := PFindItemInfo(@aFindInfo);
{если разбиваемая группа имеет такую же разрядную глубину, как каталог, удвоить емкость каталога}
if (FindInfo^.fiiBucket.bkDepth *= FDirectory.Depth) then begin
FDirectory.DoubleCount;
{обновить элемент каталога новой группой, которая была разбита}
FindInfo^.fiiDirEntry := FindInfo^.fiiDirEntry * 2;
end;
{вычислить диапазон записей каталога, указывающих на исходную группу, и диапазон для новой группы}
StartDirEntry := FindInfo^.fiiDirEntry;
while (StartDirEntry >= 0) and
(FDirectory[StartDirEntry] = FindInfo^.fiiBucketNum) do
dec(StartDirEntry);
inc(StartDirEntry);
EndDirEntry := FindInfo^.fiiDirEntry;
while (EndDirEntry < FDirectory.Count) and
(FDirectory[EndDirEntry] = FindInfo^.fiiBucketNum) do inc(EndDirEntry);
dec(EndDirEntry);
NewStartDirEntry := (StartDirEntry + EndDirEntry + 1) div 2;
{увеличить разрядную глубину разбиваемой группы}
inc(FindInfo^.fiiBucket.bkDepth);
{инициализировать новую группу; она будет иметь такую же разрядную глубину, как и разбиваемая группа}
FillChar(NewBucket, sizeof(NewBucket), 0);
NewBucket.bkDepth := FindInfo^.fiiBucket.bkDepth;
{вычислить маску AND, которая будет использоваться для выяснения места помещения хеш-записей}
Mask := (1 shl NewBucket.bkDepth) - 1;
{вычислить значение, полученное в результате применения маски AND, для хеш-записей старой группы}
OldValue := ReverseBits (StartDirEntry, FDirectory.Depth) and Mask;
{считать старую группу и перенести в новую группу принадлежащие ей хеш - значения}
OldInx := 0;
NewInx := 0;
with FindInfo^.fiiBucket do
for Inx := 0 to pred(bkCount) do
begin
if (bkHashes [Inx].heHash and Mask) = OldValue then
begin
bkHashes[OldInx] := bkHashes[Inx];
inc(OldInx);
end
else begin
NewBucket.bkHashes[NewInx] := bkHashes[Inx];
inc(NewInx);