Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Oberon
Перезагрузить страницу Реализация механизма персистентности. Порядок инициализации
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
S.Yu.Gubanov S.Yu.Gubanov вне форума
Member
 
Сообщений: 587
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.12.2002
По умолчанию Реализация механизма персистентности. Порядок инициализации - 15.08.2004, 00:58

Реализация механизма персистентности. Порядок инициализации?

Вопрос по реализации механизма персистентности (в BlackBox).
Все типы объектов желающих пользоваться механизмом персистентности модуля Stores, должны быть расширениями типа Store:
Код:
Store = POINTER TO ABSTRACT RECORD
  ...
  PROCEDURE (s: Store) Internalize- (VAR rd: Reader), NEW, EMPTY;
  ...
END;
Метод Internalize вызывается, например, при чтении объекта из файла. Внутри этого метода, в свою очередь, можно читать другой Store благодаря методу Читателя:
Код:
PROCEDURE (VAR rd: Reader) ReadStore (OUT x: Store)
Исходников реализации механизма не прилагается. Попытался придумать как это реализовать. Придумал следующее. Объекты в файле хранятся в следующем формате:[list]Мастер-хранитель читает такой файл; по "идентификатору типа" создает объекты соответствующих типов; затем у всех созданных объектов вызывает метод Internalize и вручает этому методу Reader по соответствующим бинарным данным соответствующего объекта. Когда какой-то из объектов вызывает метод Reader.ReadStore то ему выдается адрес объекта найденного по соответствующему "идентификатору объекта" - таким образом все взаимные ссылки между объектами восстанавливаются. Все вроде бы работает. Но в этом механизме есть дыра. Что если объекту придет в голову не только получить ссылку на читаемый объект ReadStore(x), а получив ее еще и обратиться к этому объекту x.DoSmth(); дело в том что может быть такая ситуация когда один из объектов, хоть и был создан, но еще не был инициализирован вызовом метода Internalize. То есть метод ReadStore(x) вернет правильную ссылку, но на еще непроинициализированный объект, а значит обращаться к нему x.DoSmth(); внутри метода Internalize опасно. Читаем что пишется про метод ReadStore(x) в документации:
Код:
PROCEDURE (VAR rd: Reader) ReadStore (OUT x: Store)
Reads a store's type, allocates it, and then reads its contents, by calling the store's Internalize procedure. x may also be NIL, or an alien if the store's module cannot be loaded, or if internalization has been cancelled by the Internalize procedure.
If the store has already been read in, a pointer to the same store is returned instead of allocating a new one. This means that arbitrary graphs that have been written with WriteStore are reconstructed correctly, including alias pointers to the same store, cycles, etc.
В документации обещается что возвращенный процедурой объект уже будет проинициализирован. Возникает вопрос, а как это можно сделать если объекты циклически ссылаются друг на друга? Первый объект вызвал ReadStore(x2) и ожидает получить уже проинициализированный объект x2, сам объект x2 внутри своего метода Internalize вызвал ReadStore(x1) и ожидает получить уже проинициализированный объект x1.
Еще раз:
1) созданы два объекта x1 и x2;
2) Запущен метод инициализации первого объекта x1.Internalize, внутри которого x1 захотел получить уже проинициализированный объект x2.
3) Запущен метод инициализации второго объекта x2.Internalize, внутри которого x2 захотел получить уже проинициализированный объект x1, что невозможно...

Парадокс?

Получается что внутри метода Internalize запрещается обращаться к только что прочитанным объектам так как некоторые из них еще могут быть не проинициализированы. Должен быть отдельный метод AfterInternalize()???
Ответить с цитированием
  (#2 (permalink)) Старый
danio danio вне форума
Member
 
Сообщений: 366
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 02.01.2004
По умолчанию 24.08.2004, 17:48

Вроде не видно ничего страшного. ReadStore может смотреть не попал ли объект уже в кэш и только в этом случае вызывать Internalize (это не совсем инициализация). В этом случае x2 получит уже якобы готовый x1. Грабли могут быть только при какой-то дополнительной рекурсивной инициализации (?), но а) это точно такой же код, программист должен следить, чтобы рекурсия сходилась б) если это какая-то переменная, то почему бы ей не оказаться на диске и не восстановиться нормальным образом.
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Организация программ с использованием механизма наследования классов Good1984))) C++ Builder 2 26.12.2011 00:21
ILINK32 Error при инициализации синглтона Leon C++ Builder 2 31.07.2011 22:09
ошибка при инициализации почты kadriolina Любые вопросы от новичков 2 22.06.2011 11:35
Можно ли добраться до кода инициализации формы Alter C++ Builder 5 19.04.2010 18:56
Советы по написанию программ с использованием механизма выбора Ahinar OpenGL 3 22.10.2009 15:24
Ошибка при инициализации приложения что делать Alley C++ Builder 1 09.03.2008 19:08
Ошибаюсь при инициализации массива ХОЛОДный PHP 6 14.02.2007 15:51
Ошибка при инициализации приложения что делать Sash'Ok! Visual C++ 5 29.09.2006 20:19
Список инициализации конструктора -=царь=- С/С++ 7 30.07.2005 02:50
Зачем блок инициализации в конструктор TNT С/С++ 8 13.05.2005 12:07
Что значит ошибка в NTDLL.DLL при инициализации MSMQ _TNT_ Visual C++ 23 06.02.2005 23:19
Корректность инициализации, настройки и запуска парсера Dr. Lecter XML & WML 0 31.10.2003 14:12



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов