oess_1: Физическая структура основного файла данных oess_1::db

Общая структура

Основной файл данных oess_1::db разделен на страницы одинакового размера. Размер страницы определяется параметром oess_1::db::storage::hard_config_t::m_page_size. Размер страницы должен быть от 16 байт до 64Kb.

Страницы делятся на блоки одинакового размера. Размер блока определяется параметром oess_1::db::storage::hard_config_t::m_chain_link_size. Размер блока должен быть не меньше 8 байт и не больше размера страницы. На странице должно размещаться целое количество блоков, без остатка.

Для всех страниц используется сквозная нумерация блоков. Первый блок на первой странице имеет индекс 0, первый блок на второй странице имеет индекс (размер страницы/размер блока).

Информация в БД сохраняется в блоках. Т.е., если объем сохраняемых данных меньше, чем размер блока, то для их хранения все равно будет выделен один блок. Если размер блока меньше, чем размер сохраняемых данных, то будет выделено несколько блоков и эти блоки будут специальным образом прописаны в цепочку.

Часть страниц хранилища выполняют специальные функции -- являются заголовками логических частей. Блоки, номера которых соответствуют этим страницам, для сохранения данных не используются.

Первая страница файла является заголовком файла. Далее файл делится на логические области, которые состоят из логических сегментов. Логические области и логические сегменты имеют собственные заголовки. Все логические сегменты состоят из одинакового количества страниц. Логические области состоят из одинакового количества сегментов за исключением, возможно, последней области. В последнюю область входит столько целых логических сегментов, сколько помещается в файл.

Структура заголовка файла

Заголовок файла можно описать следующей структурой:
struct  file_header_t
  {
    // Количество областей, в которых есть свободные блоки.
    oess_1::ushort_t  m_free_area_count;
    // Номера областей, в которых есть свободные блоки.
    oess_1::db::storage::area_ordinal_t m_free_areas[ m_free_area_count ];
  };

Первоначально, в пустом файле данных, в file_header_t::m_free_areas находятся номера всех областей файла. После того, как в какой-либо области свободные блоки заканчиваются, номер этой области из m_free_areas изымается. Если в какую-то область возвращается свободный блок, а до этого в области свободных блоков не было, то номер области возвращается в m_free_areas.

Номера областей хранятся в m_free_areas упорядоченными по возрастанию номеров.

Размер m_free_areas определяется размером страницы. Т.е. в файле данных не может быть больше, чем (размер страницы/sizeof(oess_1::ushort_t) - 1). Если в файле физически не может разместиться столько областей, сколько их можно описать в m_free_areas, то часть заголовка файла оказывается неиспользуемой.

Структура области и заголовка области

Область -- это страница заголовка области за которым следует некоторое количество логических сегментов. Размер области в сегменах зависит от того, сколько описателей сегменов поместиться в заголовке области, что зависит от размера страницы. Последняя область файла может содержать меньшее количество сегментов, если полное количество сегментов не получается разместить из-за ограничений на размер файла.

Заголовок области можно описать следующей структурой:

struct  area_header_t
  {
    // Количество сегментов, в которых есть свободные блоки.
    oess_1::ushort_t  m_free_segment_count;
    // Номера сегментов, в которых есть свободные блоки.
    oess_1::db::storage::segment_ordinal_t  m_free_segments[ m_free_segment_count ];
  };

Первоначально, в пустой области, в area_header_t::m_free_segments находятся номера всех сегментов области. После того, как в каком-либо сегменте свободные блоки заканчиваются, номер этого сегмента из m_free_segments изымается. Если в какой-то сегмент возвращается свободный блок, а до этого в сегменте свободных блоков не было, то номер сегмента возвращается в m_free_segments.

В m_free_segments хранятся относительные номера сегментов. Т.е. номера сегментов уникальны только в рамках одной области. Для полной идентификации сегмента нужно знать порядковый номер области, которой он принадлежит и порядковый номер сегмента в области.

Номера сегментов хранятся в m_free_segments упорядоченными по возрастанию номеров.

Количество сегментов, которые могут входить в область определяется размером страницы: (размер страницы/sizeof(oess_1::ushort_t) - 1).

Структура сегмента и заголовка сегмента

Сегмент -- это страница заголовка сегмента, за которым следуют страницы данных, относящиеся к этому сегменту.

Заголовок сегмента можно описать следующими структурами:

struct  block_info_t
  {
    // Собственный идентификатор блока.
    oess_1::uint_t  m_self_id;
    // Идентификатор следующего блока в цепочке.
    oess_1::uint_t  m_next;
  };

struct  segment_header_t
  {
    // Количество свободных блоков в сегменте.
    oess_1::uint_t  m_free_blocks_count;
    // Количество занятых блоков в сегменте.
    oess_1::uint_t  m_used_blocks_count;

    // Описатели свободных блоков.
    block_info_t  m_free_blocks[ m_free_blocks_count ];
    // Описатели занятых блоков.
    block_info_t  m_used_blocks[ m_used_blocks_count ];
  };

Размер сегмента зависит от размера страницы: (размер страницы/sizeof(block_info_t)). В число страниц сегмента так же входит и заголовок сегмента. Т.е. реально, в сегменте находится одна страница заголовка + (размер сегмента - 1) страниц данных. Т.к. часть блоков, которая попадает на страницу заголовка сегмента, не может быть использована, то часть segment_header_t не используется.

Для пустого сегмента segment_header_t::m_free_blocks_count содержит общее количество блоков данных сегмента, а в m_free_blocks находятся описатели этих блоков. При выделении блока под данные, его описатель перемещается из m_free_blocks в m_used_blocks. Т.о. в полностью занятом сегменте описатели всех блоков находятся в m_used_blocks.

Для свободных блоков block_info_t::m_next всегда содержит значение oess_1::db::storage_t::invalid_chain_id. Для занятых блоков block_info_t::m_next содержит идентификатор следующего блока цепочки или oess_1::db::storage_t::invalid_chain_id, если блок является последним блоком цепочки.

Алгоритм распределения блоков

При необходимости сохранения в файле данных какой-либо сущности в файле данных должна быть создана цепочка блоков достаточной для сохранения сущности емкости. Для этого последовательно выделяются блоки, в каждый блок сохраняется очередная часть сущности. Если требуется выделение еще одного блока, то он выделяется и ссылка на него помещается в block_info_t::m_next предыдущего блока.

Алгоритм выделения блоков следующий:

Этот алгоритм позволяет:


Документация по ObjESSty. Последние изменения: Fri Oct 13 18:35:37 2006. Создано системой  doxygen 1.4.7
Hosted by uCoz