Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux -> Архитектура приложений с открытым исходным кодом

Архитектура приложений с открытым исходным кодом. Том 1. Глава 4. Berkeley DB

Оригинал: "Berkeley DB"
Авторы: Margo Seltzer and Keith Bostic
Дата публикации: 2012 г.
Перевод: Н.Ромоданов
Дата перевода: октябрь 2012 г.

4.5. Компоненты, лежащие глубже

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

Во-первых, во всех подсистемах имеются свои собственные API, и первоначально в каждой подсистеме имелся свой собственный дескриптор объектов со всеми методами для конкретной подсистемы, использовавший этот дескриптор. Например, вы могли использовать менеджер блокировок из Berkeley DB для обработки ваших собственных блокировок или могли написать свой собственный отдельный менеджер блокировок, либо вы могли использовать менеджер буферирования из Berkeley DB для того, чтобы обрабатывать страницы ваших собственных файлов в разделяемой памяти. Со временем для того, чтобы упростить приложения Berkeley DB, дескрипторы, предназначенные для использования в конкретных подсистемах, были удалены из интерфейса API. Хотя подсистемы все еще являются отдельными компонентами, которые можно использовать независимо от других подсистем, теперь у них всех есть общее средство управления объектами — средство управления "средой" DB_ENV. Эта архитектурная особенность позволяет выделять слои и делать обобщения. Даже несмотря на то, что время от времени слой меняет свое положение, и все еще есть несколько мест, где к некоторой подсистеме можно получить доступ через другую подсистему, программисты могут рассматривать каждую часть системы как отдельный программный продукт с его собственными возможностями.

Во-вторых, все подсистемы (на самом деле, все функции Berkeley DB) возвращают коды ошибок через стек вызовов. Berkeley DB, как библиотека, не может для объявления глобальных переменных пользоваться пространством имен приложения, не говоря уже о том, что возврат через стек вызовов в случае ошибок является хорошей дисциплиной для программиста

Шестой урок конструирования

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

Наконец, все подсистемы поддерживают использование разделяемой памяти. Поскольку в Berkeley DB поддерживается разделение баз данных между несколькими работающими процессами, все интересуемые структуры данных должны находиться в разделяемой памяти. Наиболее значимым следствием такого решения является то, что для того, чтобы структуры данных, использующие указатели, работали в контексте нескольких процессов, в структурах данных, располагаемых в памяти, должны использоваться пары базовый адрес и смещение, а не указатели. Другими словами, вместо косвенного доступа через указатель, библиотека Berkeley DB должна создавать указатель из базового адреса (адреса, по которому сегмент разделяемой памяти отображается в память) и смещения (смещение конкретной структуры данных в соответствие с тем, как она отображена в сегменте). Для поддержки этой возможности мы написали версию пакета queue для дистрибутива Berkeley Software, в котором был реализован широкий спектр различных связанных списков.

Седьмой урок конструирования

Еще перед тем, как мы написали пакет связных списков для разделяемой памяти, инженеры Berkeley DB вручную кодировали разнообразные варианты различных структур данных, используемых в разделяемой памяти, и эти реализации рассыпались и их было трудно отлаживать. Пакет со списками для разделяемой памяти, сделанный наподобие пакетов списков BSD (queue.h), заменил все эти усилия. Как только пакет был отлажен, нам больше не потребовалось выполнять какие-либо другие отладки, касающиеся проблем связных списков в разделяемой памяти. Это иллюстрирует три важных принципа проектирования: Во-первых, если у вас есть функциональные фрагменты, которые появляются более одного раза, напишите разделяемые функции и используйте их, поскольку само по себе наличие в коде двух копий любых конкретных функциональных фрагментов гарантирует, что один из них будет реализован неправильно. Во-вторых, когда вы разрабатываете набор процедур общего назначения, напишите набор тестов для этого набора процедур для того, чтобы вы могли отладить их отдельно. В-третьих, чем труднее писать код, тем более важно чтобы он был написан и поддерживался отдельно; почти невозможно защитить окружающий код от инфицирования и раъедания со стороны некоторого фрагмента кода.


Назад К оглавлению книги Вперед