Фундаментальные алгоритмы и структуры данных в Delphi | страница 59



FHeaderRec^.hr1stDelRec := aIndex;

{количество записей уменьшилось на единицу}

dec(FCount);

dec(FHeaderRec^.hrCount);

{обновить служебный заголовок}

rsSeekStream(FZeroPosition);

rsWriteStream(FHeaderRec^, sizeof(TtdRSHeaderRec));

end;


Метод Delete, прежде всего, проверяет, была ли удалена требуемая запись. Если запись была удалена, метод вызывает ошибку. Если все в порядке, текущее значение поля первой удаленной записи служебного заголовка копируется во флаг удаления записи. Затем значение поля первой удаленной записи устанавливается равным порядковому номеру удаляемой записи, количество активных записей в массиве уменьшается на единицу и обновляется служебный заголовок в потоке.

Метод Clear аналогичен Delete, но он предназначен для удаления всех активных записей постоянного массива.

Листинг 2.25. Очистка содержимого постоянного массива


procedure TtdRecordStream.Clear;

var

Inx : longint;

DeletedFlag : longint;

begin

{выполнить цикл по всем записям и объединить их в одну цепочку удаленных записей}

for Inx := 0 to pred(FCapacity) do

begin

rsSeekStream(rsCalcRecordOffset(Inx));

rsReadStream(DeletedFlag, sizeof(longint));

if (DeletedFlag = cActiveRecord) then begin

{записать порядковый номер первой удаленной записи в первые 4 байта удаляемой записи}

rsSeekStream(rsCalcRecordOffset(Inx));

rsWriteStream(FHeaderRec^.hr1stDelRec, sizeof(longint));

{обновить значение поля первой удаленной записи служебного заголовка, чтобы оно указывало на удаляемую запись}

FHeaderRec^.hr1stDelRec := Inx;

end;

end;

{записей нет}

FCount := 0;

FHeaderRec^.hrCount := 0;

{обновить служебный заголовок}

rsSeekStream(FZeroPosition);

rsWriteStream(FHeaderRec^, sizeof(TtdRSHeaderRec));

end;


Этот метод выполняет цикл по всем записям массива и, если запись активна, удаляет ее в соответствии с алгоритмом, используемым в методе Delete.

Класс TtdRecordStream позволяет также в один прием увеличивать емкость потока на несколько записей, а не добавлять записи по одной с помощью метода Add. Такая возможность позволяет зарезервировать место под постоянный массив, если заранее известно количество записей, которое будет в нем храниться. Запись свойства Capacity осуществляется через метод rsSetCapacity.

Листинг 2.26. Задание емкости постоянного массива


procedure TtdRecordStream.rsSetCapacity(aCapacity : longint);

var

Inx : longint;

begin

{допускается только увеличение емкости}

if (aCapacity > FCapacity) then begin

{заполнить текущую запись нулями}

FillChar(FRecord^, FRecordLen4, 0);