Quasi Single Page (QSP) - elegant and automatic persistence for Objective-C

This new method of making objects and data structures persistent is applicable to any C-related language, but is particularly suitable to Objective-C.

The basic idea is simple: If all objects are allocated from one page of virtual memory, storing the data to disk is reduced to copying this page to disk. Opening the data requires to copy it back to memory, but because it is usually in a different location, we have to add the same offset to all the pointers stored in the individual objects

In most application, it is not practical to work with just one page of memory. We add pages as we create more objects. In QSP, we add pages as required. However, before storing the data to disk, we convert all the pages to one larger page which is then stored on disk. This conversion is done without using additional memory, and QSP converts all the pointers to reflect the new representation. The data stored on the disk have always the one-page representation, and are opened as a single page, to which we can add pages as needed.

If we know where the pointers are, their conversion to one page is easy. For a fast detection of pointer locations, QSP keeps a bitmap which is similar to the one used in DOL Memory Blasting. This bitmap stores one bit for every potential pointer location on the page and, on a 32-bit hardware, it creates only a minor (1/32 of the page) overhead. When allocating an object, QSP marks its pointer locations by setting corresponding bit to 1. When converting pointers, QSP does not search through individual objects. It runs through the bitmap, and converts memory locations marked by 1 in the bitmap.

Because Objective-C has reflection, the persistency is fully automatic. You only add the same statement to each application class. For example, to make classes Author and Book persistent, you only have to add the green lines in the code below. When using InCode library, ZZds is automatically generated - it inserts all the pointers and other pieces required for the data structures (associations)

@interface Author : PersistObject
{
... any non-pointer members
@public
ZZ_Author ZZds;
}
PersistInterface;
- (id) ptrList;
@end

@interface Book : PersistObject
{
... any non-pointer members
@public
ZZ_Book ZZds;
}
PersistInterface;
- (id) ptrList;
@end