Предположим, у вас есть большой файл, состоящий из группы блоков фиксированного размера. Каждый из этих блоков содержит некоторое количество записей переменного размера. Каждая запись должна полностью помещаться в один блок, и тогда такие записи по определению никогда не будут больше, чем полный блок. Со временем записи добавляются и удаляются из этих блоков по мере того, как записи приходят и уходят из этой «базы данных».
В какой-то момент, особенно после того, как, возможно, многие записи будут добавлены в базу данных и несколько удалены, многие из блоков могут оказаться заполненными только частично.
Каков хороший алгоритм для перетасовки записей в этой базе данных, чтобы сжать ненужные блоки в конце файла, лучше заполняя частично заполненные блоки?
Требования к алгоритму:
- Сжатие должно происходить вместо исходного файла без временного расширения файла более чем на несколько блоков от его начального размера.
- Алгоритм не должен излишне нарушать блоки, которые уже в основном заполнены.
- Целые блоки должны быть прочитаны или записаны из / в файл за один раз, и следует предполагать, что операция записи относительно дорога.
- Если записи перемещаются из одного блока в другой, они должны быть добавлены в новое место перед удалением из исходного положения, чтобы в случае прерывания операции записи не были потеряны в результате «неудачного» уплотнения. (Предположим, что это временное дублирование таких записей может быть обнаружено при восстановлении).
- Память, которую можно использовать для этой операции, может быть порядка нескольких блоков, что составляет очень небольшой процент от общего размера файла.
- Предположим, что записи имеют порядок от 10 до 1 Кбайт со средним размером около 100 байт. Блоки фиксированного размера имеют порядок 4K или 8K, а файл - порядка 1000 блоков.