
Диплом К
.pdf
Отличия ССС от записи состоят в том, что ссылка на предыдущую страницу у первой страницы в списке также нулевая (как и ссылка на следующую страницу у по-
следней страницы в списке). Таким образом, ССС – простой двунаправленный список страниц. Номера первой и последней свободных страниц и общее их количество хра-
нятся на нулевой странице (см. рис. 9).
3.3.3. Иерархия классов В соответствии с технологией объектно-ориентированного программирования для
реализации разрабатываемого DS–файла была построена иерархия классов, представ-
ленная на рис. 14. Каждый класс охватывает определенную область реализации DS–
файла. Ниже кратко описаны функции каждого класса. Подробное описание классов верхнего уровня (dsFile, dsRecord) дано в следующем разделе.
|
dsFile |
|
dsPool |
dsRecord |
dsFPL |
|
dsPage |
dsArray<SPN> |
|
dsCache |
|
Äèñê |
|
|
|
Рис. 14. Иерархия классов DS–файла |
|
3.3.3.1. Класс dsCache
Класс самого нижнего уровня. Методы только этого класса непосредственно про-
изводят ввод/вывод на диск. Класс предназначен для кэширования страниц всех DS–
файлов, открываемых одной программой. В программе существует только один объект класса dsCache, который создается при создании первого объекта класса dsPage. При открытии нового DS–файла он регистрируется в кэше, передавая максимальное число страниц, которое может одновременно находится в кэше для этого файла. При реги-
страции каждому открытому DS–файлу присваивается уникальный идентификатор пользователя кэша. При последующем обращении к объекту класса dsCache для разли-
чения DS–файлов используется этот идентификатор.
Кэшируется как чтение из файла, так и запись в него. При чтении страница снача-
ла считывается в кэш–буфер, а затем передается прикладной программе. При записи страница помещается в кэш–буфер. Если кэш заполнен, то происходит поиск страницы,
которая дольше всего не использовалась (данный метод обычно называется LRU – Last
Recent Using), и она выталкивается из кэша. Причем, если эта страница изменялась по-
сле считывания из файла (или вообще это новая страница файла), то она записывается на диск. Существует режим кэширования, при котором при выталкивании из кэша из-
мененной страницы ее запись на диск не производится, а фиксируется ошибка. Данный режим с успехом может использоваться при создании демонстрационных версий при-
кладных программ. При этом работа программы будет продолжаться до переполнения памяти, после чего продолжение работы станет невозможным.
3.3.3.2. Класс dsPage
Данный класс предназначен для манипуляций с файлом на уровне страниц. В пе-
речень операций входят: чтение и запись определенной страницы или ее части (послед-
нее обычно применяется для нулевой страницы), удаление страницы и позиционирова-
ние на определенную страницу по ее номеру.
Кроме того, объекты этого класса создают, открывают и закрывают файл на диске.
3.3.3.3. Класс dsRecord
Предназначен для манипуляций с файлом на уровне записи. В число важнейших операций входят: добавление, чтение, запись, удаление записи.
3.3.3.4. Класс dsFPL
Предназначен для поддержки ССС (FPL – Free Page List). Данный класс является потомком класса daArray<SPN> (daArray – метакласс, реализующий массив переменной длины из элементов произвольного типа). При помощи этого класса производится кэ-
ширование всех номеров страниц из ССС. Это значительно ускоряет операции добавле-
ния и изменения записи при увеличении ее размера, так как не надо считывать с диска
ССС, чтобы определить номера страниц из ССС. Необходимость кэширования ВСН'ов страниц CCC задается одним из параметров при создании и открытии DS–файла.
3.3.3.5. Класс dsPool
Предназначен для организации еще одного кэша – так называемого пула ВСН'ов записей. Для каждой записи, которая считывается или записывается в файл, в пуле со-
храняются ВСН'ы страниц, составляющие запись. В результате при повторном обраще-
нии к записи нет необходимости заново сканировать запись для определения того, какие страницы в нее входят. Особенно это эффективно при изменении длинных записей.
Пул представляет собой двумерный массив, каждая строка которого содержит ВСН'ы какой-либо одной записи. Так как записи могут содержать различное число страниц, то длина строки пула (первое измерение массива) принимается по числу стра-
ниц в самой большой записи DS–файла, а за последним ВСН'ом в строке пула ставится
0 для обозначения конца цепочки. При добавлении более длинной записи происходит перевыделение пула с увеличенным первым измерением. Число строк (второе измере-
ние массива) ограничено (чтобы избежать переполнения памяти) и задается в параметре bSaveInPool при конструировании DS–файла. Это число показывает, ВСН'ы какого ко-
личества записей можно будет поместить в пул одновременно. При записи, чтении или изменении любой записи в DS–файле ее ВСН'ы помещаются в пул. Если в пуле нет ме-
ста для новой записи, то из него удаляется список ВСН'ов для записи, которая дольше всего не использовалась (стратегия LRU).
3.3.3.6. Класс dsFile
Класс верхнего уровня иерархии. Наследует от класса dsRecord методы управле-
ния записями. Объединяет в логическое целое пул ВСН'ов страниц, ССС и собственно файл с его кэшем и страничной организацией.

3.3.4. Описание реализации
В данном разделе описаны наиболее существенные методы работы с DS–файлом.
Прототипы методов обведены в рамку, далее следует описание метода и всех парамет-
ров. Полный перечень методов с кратким описанием приведен в табл. 1 в конце раздела.
В табл. 2 приведен список всех регистрируемых в процессе работы ошибок.
3.3.4.1. Конструктор создания файла
dsFile |
(word |
wPageLen, |
|
|
char* |
lpszFileName, |
|
|
char* |
lpUserArea |
= NULL, |
|
byte |
bMode |
= DS_DEF_MODE_OPEN, |
|
word |
wSizeCache |
= DS_DEF_SAVE_CACHE, |
|
byte |
bSaveInPool |
= DS_DEF_SAVE_POOL) |
Данный конструктор предназначен для создания нового DS–файла. Параметры
конструктора:
wPageLen – размер страницы DS-файла; Значение должно находиться в пределах
от 64 до 64000 байт. Рекомендуется задавать значение либо кратное 512 (размер сектора
DOS), либо делитель числа 512.
lpszFileName – имя создаваемого файла.
lpUserArea – адрес данных пользователя, помещаемых в область пользователя в
заголовке DS–файла на нулевой странице. По умолчанию записывать в область пользо-
вателя ничего не требуется. Длина области пользователя в заголовке DS-файла – 8 байт.
wSizeCache – задает размер кэша в страницах. По умолчанию принимается 100
страниц, максимум – 1000 страниц. |
|
bSaveInPool – число строк в пуле. По умолчанию принимается значение |
50 |
строк, максимум – 100 строк. |
|
bMode – флаги режимов работы созданного DS-файла. Имеются следующие фла-
ги:
DS_O_RDONLY – файл открывается только на чтение;
DS_O_ARCHIVE – задает сжатие записываемых данных; Этот режим требует дополнительного буфера в памяти размером 50000 байт . На текстовых данных

процент сжатия колеблется от 35% до 55%. Кроме того сжатие данных при-
мерно в 1.7 раза увеличивает длительность добавления записей в DS-файл, но на скорости чтения почти не сказывается.
DS_O_FASTDEL – разрешение кэширования ВСН'ов ССС. См. также раздел
3.3.3.4. Данный режим устанавливается по умолчанию.
DS_O_CACHE – режим кэширования страниц при работе с файлом. См. также раздел 3.3.3.1. Данный режим устанавливается по умолчанию.
DS_O_CACHE_ONLY – режим работы только с кэшем. В этом режиме запре-
щается записывать данные из кэша в файл. Служит для создания демонстраци-
онных версий программ.
3.3.4.2. Конструктор открытия файла
dsFile |
(char* |
lpszFileName, |
|
|
byte |
bMode |
= DS_DEF_MODE_OPEN, |
|
word |
wSizeCache |
= DS_DEF_SAVE_CACHE, |
|
byte |
bSaveInPool |
= DS_DEF_SAVE_POOL) |
Данный конструктор предназначен для открытия уже существующего DS–файла.
При отсутствии файла с заданным именем будет зафиксирована ошибка dsPage_ErrFName. Все параметры имеют то же самое значение, что и при создании DS–
файла.
3.3.4.3. Добавление записи
SPN Add |
(char* |
FromAdd, |
|
|
word |
SizeAdd, |
|
|
byte |
AttrAdd |
= 0) |
Метод добавляет запись в DS–файл. При включенном режиме сжатия запись упа-
ковывается. Формируется заголовок записи. Данные разбиваются на необходимое число страниц и записываются в файл с установлением соответствующих ссылок. ВСН'ы за-
писанных страниц помещаются в строку пула. Параметры метода:
FromAdd – адрес записи в памяти
SizeAdd – размер записи в памяти в байтах

AttrAdd – атрибут записываемой записи. В текущей реализации базы данных ис-
пользуются следующие атрибуты: 0 – запись пользователя, 1 – системная запись
(например, каталог деревьев в индексном файле).
Возвращает – ВСН добавленной записи.
3.3.4.4. Чтение записи
word Read |
(SPN |
ReadSPN, |
|
char*& |
ToRead, |
|
word& |
SizeRead) |
Параметры:
ReadSPN – ВСН головной страницы записи
ToRead – адрес буфера, куда следует помещать считанные данные. Если размер записи неизвестен, возможно задание этого параметра нулевым, после чего метод сам выделит память под размер записи.
SizeRead – размер памяти выделенной под буфер. Этот параметр проверяется внутри метода на предмет достаточности буфера для размещения данных DS-записи.
Если ToRead задан нулевым, то значение SizeRead вернет размер буфера, который будет выделен внутри метода.
Возвращает – размер считанной записи или 0 при любой ошибке, кроме ошибки dsRECORD_NoMemory.
Производит считывание всех страниц записи, собирая данные в один буфер. Про-
изводится контроль на достаточность буфера для считывания всей записи, в случае не-
хватки места фиксируется ошибка dsRECORD_NoMemory, но метод все равно возвра-
щает длину записи, а параметр SizeRead – необходимую длину буфера. Если буфер вы-
деляется самим методом, то выделение производится с выравниванием по границе страницы. Если данные записи были сжаты, то производится их распаковка. ВСН'ы счи-
танных страниц помещаются в пул.

3.3.4.5. Изменение записи
word Replace |
(SPN |
ReplaceSPN, |
|
|
char* |
From, |
|
|
word |
Size, |
|
|
byte |
Attr |
= 0) |
Параметры:
RepalceSPN – ВСН обновляемой записи
From – адрес измененной записи
Size – размер измененной записи в байтах
Attr – новый атрибут записи
Возвращает – число записанных байт. Эта величина может отличаться от длины записи, так как последняя страница записывается полностью, независимо от степени ее наполнения.
Сначала делает все аналогично методу Add (см. раздел 3.3.4.3.), но записывает данные не на свободные страницы, а на страницы, прежде занятые обновляемой запи-
сью. Если запись стала короче, то оставшиеся хвостовые страницы помещаются в ССС,
иначе из ССС берется необходимое количество свободных страниц. Производит необ-
ходимые модификации пула.
3.3.4.6. Удаление записи
void Del (SPN DelSPN)
Параметры:
DelSPN – ВСН удаляемой записи
Определяет цепочку ВСН'ов страниц удаляемой записи и помещает ее в ССС, в за-
головке головной странице флаг занятости устанавливается в 0. При наличии удаляемой записи в пуле соответствующая ей строчка пула обнуляется.
3.3.5. Заключение Разработанная библиотека функций полностью соответствует техническому зада-
нию. Реализованы широкие возможности по управлению файлом данных для базы дан-
ных.
Имеется возможность работы с записями переменной длины в файле данных (до-
бавление, чтение, изменение, удаление). Исследование поведения разработанной биб-
лиотеки в зависимости от ряда параметров приведены в исследовательской части ди-
пломной работы.
|
Табл. 1. Список методов класса dsFile |
|
|
Название |
Назначение |
|
|
AbortTransaction |
Аварийное завершение транзакции. Отмена всех сделан- |
|
ных в ходе транзакции изменений |
|
|
ActiveTransaction |
Возвращает уровень вложенности текущей транзакции (0 |
|
– если транзакция не активна) |
|
|
Add |
Добавление новой записи в файл данных. Возвращает |
|
ВСН добавленной записи |
|
|
AmountRecord |
Возвращает число записей в DS–файле |
|
|
Archive |
Возвращает признак сжатия записей (1 – записи сжима- |
|
ются, 0 – не сжимаются) |
|
|
BeginTransaction |
Начало транзакции в файле данных |
|
|
Clear |
Очистка файла данных. Все записи удаляются |
|
|
ClearError |
Сброс признака ошибки |
|
|
DataLenFirstPage |
Возвращает полезное пространство в байтах, которое от- |
|
водится на головной странице |
|
|
DataLenSecondPage |
Возвращает полезное пространство в байтах, которое от- |
|
водится на хвостовой странице |
|
|
Del |
Удаление записи из файла |
|
|
dsError |
Возвращает текущий код ошибки |
|
|
EndTransaction |
Нормальное завершение транзакции |
|
|
Flush |
Принудительная запись всех кэш–буферов на диск. Га- |
|
рантирует, что все сделанные изменения запишутся на |
|
диск |
|
|
GetAttr |
Возвращает атрибут текущей записи |
|
|
GetFileName |
Возвращает имя DS–файла |
|
|
GetLenPage |
Возвращает размер страницы DS–файла |
|
|
LenRec |
Возвращает длину текущей записи |
|
|
LenRecord |
Возвращает длину заданной записи |
|
|
Название |
Назначение |
|
|
MaxLenRecord |
Возвращает длину наибольшей записи |
|
|
Read |
Считывает запись из файла |
|
|
ReadAttr |
Считывание атрибута заданной записи |
|
|
ReadPart |
Считывание части заданной страницы (чаще всего нуле- |
|
вой) |
|
|
Replace |
Изменение записи в файле |
|
|
RunTransaction |
Возвращает признак активности транзакции |
|
|
Seek (вариант 1) |
Делает заданную запись текущей |
|
|
Seek (вариант 2) |
Делает первую/последнюю/следующую/предыдущую за- |
|
пись текущей |
|
|
SetUserArea |
Запоминает данные пользователя в поле User нулевой |
|
страницы |
|
|
SizePageFile |
Возвращает размер DS–файла в страницах |
|
|
TotalSize |
Возвращает размер DS–файла в байтах |
|
|
UserArea |
Возвращает пользовательские данные (поле User |
|
с нулевой страницы) |
|
|
WritePart |
Запись части заданной страницы (чаще всего нулевой) |
|
|