|
Материалы книги получены с http://www.itlibitum.ru/
Оптимизация объема
Другое решение - реорганизация структур данных для сокращения издержек, связанных с хранением незаблокированных ConstPtr (хотя и ценой некоторой потери скорости). ConstPtr лишь незначительно отличается от указателей только для чтения, которые рассматривались в главе 6 и не имели ничего общего с транзакциями: он имеет ссылку на ConstPtr и функцию Lock(). Мы избавимся от первого и внесем некоторые изменения во второе.
Представьте себе глобальную структуру данных (вероятно, хранящуюся в виде статического члена класса Transaction), в которой находится информация о том, какие Transaction блокируют какие ConstPtr. Для каждой пары в таблице содержится соответствующий LockPtr. Каждый раз, когда вызывается функция Lock() класса ConstPtr, она проверяет, присутствует ли this в таблице. Если присутствует, функция сравнивает транзакцию, переданную в качестве аргумента, с находящейся в таблице. Если ConstPtr не находит себя в таблице, он включает в нее новый триплет (ConstPtr, Transaction, LockPtr), а если находит с другой транзакцией - инициирует исключение.
Такая схема оказывается более экономной, чем описанная выше; она не тратит память на значения NULL для всех незаблокированных объектов. Разумеется, она сложенее и медленнее работает - структура данных еще только разогревает двигатель на старте, а косвенной обращение через переменную класса уже пересекает финишную черту.
Возможно, у вас возник вопрос - а почему функция Lock() должна оставаться с ConstPtr? Почему ее нельзя включить в другой класс или даже сделать глобальной функцией? Если мы избавимся от переменной LockPtr* и функции Lock(), ConstPtr превратится в самый обычный указатель только для чтения, который на вопрос о транзакциях лишь тупо смотрит на вопрошающего. Впрочем, так ли это? LockPtr по-прежнему приходится объявлять другом; следовательно, хотя бы тривиальных изменений не избежать. Более того, Transaction не знает конкретный тип указываемого объекта и потому не может использовать шаблон LockPtr для создания объекта блокировки. Если вы еще не забыли, абстрактный базовый класс Lock создавался именно для этой цели. Увы. Нам хотелось бы оставить ConstPtr в счастливом неведении… но не суждено.
Назад Содержание Далее
|