52704.fb2 Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 119

Фундаментальные алгоритмы и структуры данных в Delphi - читать онлайн бесплатно полную версию книги . Страница 119

hdStoreToStream;

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;