52704.fb2
FList.Free;
inherited Destroy;
end;
procedure TtdHashDirectory.hdStoreToStream;
begin
FStream.Seek(0, soFromBeginning);
FStream.WriteBuffer(FDepth, sizeof(FDepth));
FStream.WriteBuffer(FCount, sizeof(FCount));
FStream.WriteBuffer(FList.List'4, FCount * sizeof(longint));
end;
Методы предка (листинг 723) свойства Items просто извлекают данные, однотипные longint, из внутреннего объекта TList.
Листинг 7.23. Установка и извлечение значений каталога
function TtdHashDirectory.hdGetItem(aInx : integer): longint;
begin
Assert( (0 <= aInx) and (aInx < FList.Count),
hdErrorMsg(tdeIndexOutOfBounds, 'hdGetItem', aInx));
Result := longint(FList.List^[aInx]);
end;
procedure TtdHashDirectory.hdSetItem(aInx : integer;
aValue : longint );
begin
Assert ((0 <= aInx) and (aInx < FList.Count), hdErrorMsg(tdeIndexOutOfBounds, 'hdGetItem', aInx));
FList.List^[aInx] := pointer(aValue);
end;
И, наконец, в листинге 7.24 приведен код интересного метода класса, который вдвое увеличивает размер каталога.
Листинг 7.24. Увеличение вдвое количества записей в каталоге
procedure TtdHashDirectory.DoubleCount;
var
Inx : integer;
begin
{удвоить значение счетчика, увеличить глубину}
FList.Count := FList.Count * 2;
FCount := FCount * 2;
inc(FDepth);
{теперь каждая запись в исходном каталоге удваивается; например, значению в записи 0 старого каталога теперь соответствует значение для записей 0 и 1 нового каталога}
for Inx := pred(FList.Count) downto 1 do
FList.List^[Inx] := FList.List^[Inx div 2];
end;
Во-первых, этот метод удваивает значение счетчика элементов во внутреннем объекте TList. Реализация TList гарантирует установку новых элементов в нулевые значения, хотя, как вскоре будет показано, это не имеет никакого значения. Метод удваивает значение внутреннего счетчика и увеличивает значение разрядной глубины. Затем мы копируем и удваиваем все элементы объекта TList (чтобы убедиться, что цикл работает правильно, советуем во время изучения этого материала обращаться к рисункам 7.1 (е) и 7.1 (f)).
Этот класс выполняет ряд важных подготовительных действий, необходимых для работы нашего основного класса TtdHashTableExtendible, код интерфейса которого приведен в листинге 7.25.
Листинг 7.25. Интерфейс класса TtdHashTableExtendible
type
TtdHashTableExtendible = class private
FCompare : TtdCompareRecordKey;
FCount : longint;
FDirectory: TtdHashDirectory;
FHashFunc : TtdHashFuncEx;
FName : TtdNameString;
FBuckets : TtdRecordStream;