Он должен динамически распределять память под объекты в ПАП, выделять подходящие куски памяти для новых объектов, объединять свододные области при удалении объектов. Добавлено (2010-01-17, 23:33)
---------------------------------------------
Фактически он должен реализовать функции malloc и free для ПАП, и своих структуры хранить тоже в ПАП.
Его структуры должна начинаться по нулевому адресу ПАП. Первым делом когда мы открываем хранилище мы должны прочитать состояние менеджера ПАП и узнать где какие объекты хранятся в ПАП что бы составить таблицу размещения персистных объектов.
Добавлено (2010-01-17, 23:59)
---------------------------------------------
МОРДОР добавь Олега в TH Team
Добавлено (2010-01-18, 00:17)
---------------------------------------------
Цепочки состояния менеджера ПАП наверно не стоит размазывать по всему ПАП, а кучковать группами например по 1024 объекта.
Каждое звено состояния цепочки менеджера можно сделать примерно следующей структурой:
Code
struct BlockInfo
{
unsigned ObjectID; // Если = 0 значит область ПАП свободна и является кандидатом на объединение
unsigned PersistAddress; // Адрес в ПАП
unsigned ObjectSize; // Размер объекта
unsigned NextBlobk; // Указатель на следующее звено состояния менеджера в ПАП
};
в принципе BlockInfo тоже является персистным объектом
Добавлено (2010-01-18, 00:28)
---------------------------------------------
Code
// persist template class for primitive c++ types
template <class _T>
class persist
{
friend class fptr<_T>;
typedef _T& _Tref;
typedef _T* _Tptr;
//union{
// _T val;
unsigned char _data[sizeof(_T)];
//};
void get_name( char* faddress )
{
//strstreambuf buf( faddress, faddress_size );
//iostream bufstream( &buf );
union convert
{
persist<_T>* a;
unsigned b;
} c;
c.a = this;
//bufstream << "./" << c.b;
//bufstream.put(0);
char str[10];
_ultoa( c.b, str, 16 );
strcpy( faddress, ".\\Obj_" );
strcat( faddress, str );
strcat( faddress, ".persist" );
}
public:
persist()
{
char faddress[faddress_size];
faddress[0] = 0;
get_name( faddress );
//memset( (char*)(&_data[0]), 0, sizeof(_T) ); -- уже не нужно
// вызываем принудительно конструктор
new((void*)_data) _T;
ifstream( faddress ).read( (char*)(&_data[0]), sizeof(_T) );
}
persist(const _T& ref) : (*(_T*)_data)(ref) {}
~persist()
{
char faddress[faddress_size];
get_name( faddress );
ofstream( faddress ).write( (char*)(&_data[0]), sizeof(_T) );
// вызываем принудительно деструктор
((_T*)_data)->~_T();
}
operator _Tref() { return (*(_T*)_data); }
operator _Tref() const { return (*(_T*)_data); }
_T* operator&() { return &(*(_T*)_data); }
_Tref operator=( const _T& ref ) { return (*(_T*)_data) = ref; }
};