C Permanent Object Storage (Persistent Object Storage for C )
Introduction Description Object Type Allocated and Release Objects from Memory A Permanent Object Protocol Memory Constructor Open Memory POST Installation Post Class Library and Post Use STL Class Replacement Standard Distribution Son How to Use POST Detail About POST More information
Introduction
Post provides simple and effective storage for application objects. Post is based on memory file mirroring mechanism and page image processing. Post eliminates the overhead of permanent object access. In addition, Post supports multi-storage, virtual functions, data update atomic operations, efficient memory allocation, and optional garbage collectors for specifying memory mode. Post can also work well Inherit and contain the object of the pointer.
Describe the object type
Post Storage Management requires some information to allow a permanent object type to support garbage collectors, load time reference repositioning and initialization virtual table internal function pointers. But unfortunately, the C language does not provide a mechanism to provide these information from the class during the runtime. In order to avoid using some special tools (preprocessors) or "dirty kid" paths (acquisition information from debug information), this information must be specified by programmers. These, called the class registrar can be implemented simply by some macro provided by Post .
POST invokes the default constructor when the object is overloaded from the memory to initialize the object. In order to make the object handle can be stored, the programmer must include macro classInfo (name, field_list) in the class definition. Name indicates the name of the object. Field_List describes the reference field of the class. Three macros are defined in the header file ClassInfo.h definitions of the description field:
Re (x)
Describe a field.
Refs (x)
Describe a one-dimensional fixed array field. (Eg, a set element).
VREFS (X)
Describe the variable one-dimensional array field. Variable groups can only be the last member of the class. When you define a class, you can specify an array containing only one element. The number of elements in the specific object instance can be specified when generated.
These macro lists must be separated by spaces: REF (a) ref (b) REFS (C). Macro ClassInfo defines the default constructor (constructor without parameters) and class descriptor. Class descriptor is a static member of the class Named self_class. Such foo descriptors can be accessed through foo :: self_class. The default constructor of the base class and member is automatically called by the compiler, and you don't have to worry about calling them. However, structural members in the serialized class should not forget to use the ClassInfo macro in the structural definition. This class is then registered via a memory to enable it to be accessed. This process is completed by Macro Register (Name). The class name will be placed in the memory together. When the memory is turned on, the class is mirrored between the storage and applications. Compare the class names in the memory and class names in the program. If there is a class that is not subject to the program definition or the application and the class in the memory, the program assertion will fail.
The following example explains these rules:
Struct branch {
Object * Obj;
Int key;
ClassInfo (Branch, Ref (OBJ));
}
Class foo: public object {
protected:
Foo * Next;
Foo * prev;
Object * arr [10];
Branch branches [8];
INT X;
Int Y;
Object * childs [1];
PUBLIC:
ClassInfo (FOO, REF (NEXT) REF (Prev) REFS (ARR) VREFS (Linked));
Foo (int X, int y);
Register (1, foo);
MAIN () {
Storage my_storage ("foo.odb");
IF (my_storage.open ()) {
MY_ROOT_CLASS * ROOT = (my_root_class *) my_storage.get_root_Object ();
IF (root == null) {
Root = new_in (my_storage, my_root) ("Some Parameters for root";
}
...
INT N_CHILDS = ...;
SIZE_T VARYING_SIZE = (n_childs-1) * sizeof (Object *);
// We Should Subtract 1 from n_childs, Because ONE Element is Already
// Present in fixed part of class.
Foo * fp = new (foo: self_class, my_storage, varying_size) foo (x, y);
...
MY_Storage.close ();
}
}
Assign and release objects from memory
Post provides a special memory distribution sub-distribution sub-distribution to manage storage memory. This distribution sub-use method: for allocating small objects and large objects. All storage memory is divided into a page (the page size of the page is not related to the page size of the operating system, and the current version of Post has a 512 byte). Small objects are such objects, their size is less than or equal to 256 bytes (page Size / 2). These objects are allocated into a block linked to a fixed size. Each chain contains the same size block. The size of the assigned object is in units of 8 bytes. The number of chains containing these blocks by 256 for each object is preferably not greater than 14 (different equalization page number). POST allocates an object header before each object, contains object identification and object size. Considering that the head is just 8 bytes, and the size of the object in C is more than 0, the block chain of size 8 can be discarded. Allocation and release small objects are usually very fast: just insert / delete operations from the L1 queue. If the chain is empty and we try to assign new objects, the new page is allocated to store objects like current sizes (Page is divided into blocks to add to the list). The space required for large objects (greater than 256 bytes) is allocated from the idle page queue. The size of the large object is aligned. POST uses the first feed to maintain an idle page queue (free sections of all pages and follow the current position of the queue with a special pointer). Realization of storage management See file storage.cxx
Using explicitly or implicit memory release depends on programmers. Explicit memory release is fast (especially for small objects) but implicit memory release (garbage collection) is more reliable. Use the logo and clear garbage collection mechanisms in Post . There is a special object in the store: root object. The garbage collector first flags all objects can be accessed by root objects (that is, can arrive from root objects, and through reference traverses). This is released in the first GC phase. The garbage collector can be generated when the object is loaded from the file (if you pass the Do_Garbage_collection property to the Storage :: Open () method). You can also call the garbage collector during the program running :: do_mark_and_sweep () method. But be sure to determine that the object that is not directed by the program variable cannot be accessed from root object (these objects will be released by GC).
Based on multi-inheritance C classes can have non-zero offset in the object and may be referenced within the object. This is why we use special technology to access the object header. The POST maintenance page assignment bitmap, where each bit corresponds to the page in the memory. If some big object is assigned to a few pages, all these objects occupied by the items corresponding to the first except for 1. All other pages have corresponding liquiditations in the bitmap. To find an object start address, we first arrange the pointer value by page size. Then POST finds the object start page from the bitmap (this page has zero in the bitmap). Then remove the information of the object size from the object header included in the page. If the size is greater than half of the page size, we have found an object description: it is at the beginning of this page. Viorently in calculating the size of the fixed blocks used in the page and calculates the page's pointer offset by block size. This head positioning scheme is used by the garbage collector, and class Object defines the Operator Delete, and is used by the method of parsing object size and class information from the object header. A special overloaded NEW method is provided in Post for storage of object assignments in storage. This method needs to create a class description of an object, create a memory of the object, and the size of the optional object instance variable part as an additional parameter. Macro New_IN (Storage, Class) Provides a permanent object to create "syntax". Permanent objects can be redefined with Operator delete deletion.
Permanent object protocol
All permanent objects in Post must inherit the class Object defined in Object.h. This class does not contain any variables and provides a method of obtaining / release objects and runtime. The class Object can be a multi-inheritance class (the order of the base class does not matter). Each permanent class must have a constructor for the POST system (see the Described Object Class section). This means that you cannot initialize the constructor without parameters. If your class constructor does not even have meaningful parameters, you must add a fictional to the constructor created with the macro ClassInfo.
In order to access the object programmer in the permanent memory needs a certain root object, it can access each other object with a normal C pointer. POST memory provides two ways to specify and get references to root objects:
Void set_root_object (Object * Obj);
Object * get_root_Object ();
Get_root_Object () returns NULL when you create a new store. You need to create root objects through the set_root_object () method and save a reference. When you open the store next time, the root object can be obtained via GET_ROOT_OBJECT ().
Tip: The class is usually changed during program development and maintenance in practical applications. Unfortunately, POST is not provided with a tool that does not provide automatic object conversion (see Lazy Object Update Design Examples in Goods), so in order to avoid adding new fields to objects, I can only suggest that you keep some space in the object. In the future. This is especially significant for root objects because it is a preferred person of the newly added object. You also need to avoid the reference to the root object. If there is no other object contains a reference to the root object, the root object can be simply changed (via the set_root_object method) to the new class instance. POST storage provides a way to set up and obtain the village publishing identity. This logo can be used to update the object in the memory based on the memory and application version.
Memory constructor
You can use several memories while using it. The memory constructor has a necessary parameter - stores the file path. If this file has no extension, then POST adds a suffix ".oDB" for the file name. This file name is also used by post to form a few auxiliary files:
Document Description Using Timators Contains Timetable for New Memory Images in Non-Works Save Memory New Image ".tmp" Transaction Record File Used in Transaction Mode ".log" Save Memory File Backup is only for Windows -95 Reduced Name Temporary File ".sav" The other two parameters of the memory constructor have default. The first parameter MAX_FILE_SIZE indicates that the memory file extension is limited. If the memory file is greater than Storage :: max_file_size, it will not be removed but it is impossible to extension. If max_file_size is greater than the file size, behavior depends on the mode of opening the memory. In transaction mode, the file is mirrored to memory under read and write protection. Windows-NT / 95 extension file size to max_file_size. The file size is shortened by the Storage :: Close () method to the boundary of the last object in the memory. In Windows, in order to open the memory in the read and write mode, you need to have at least the number of idiots :: max_file_size on the disk. Even if you are not ready to join the new object.
The last parameter of the memory constructor is MAX_LOCKED_OBJECTS, which is only used in transaction mode to provide a buffer of write a transaction record file in the mirror page. In order to provide data consistency Post must ensure that the modification page is saved in the transaction record file before the image is refreshed. Post uses one of two ways: synchronous record writing (MAX_LOCKED_OBJECTS == 0) and buffering written in the page in memory. By locking the page in memory, we can ensure that it is not swapped on the disk in transaction recording buffering money. The mirror page is written to the transaction record file in an asynchronous mode (including enabling the operating system buffer). When the number of locked pages exceeds max_locked_pages, the record file buffer is refreshed on disk and all locks are unlocked. This method can significantly improve transaction processing capabilities (5 times in NT). But unfortunately, different operating systems use different methods to lock the page in memory.
Windows 95 does not support it. In the Windows NT, each process can lock its page, but the total number of locks is not allowed to exceed the process of running configuration restrictions. In the default, the process can lock more than 30 pages. If you specify the max_locked_pages parameter greater than 30, Post will try to extend the process to configure your needs. But from my experience to see the gap between the performance between 30 and 60 locked pages is very small. Only superusers under UNIX can lock the page in memory. This is why the file constructor checking the process has sufficient permissions to use the lock operation. So if you specify the max_locked_pages parameter greater than 0, then you will decide to use synchronization or asynchronous write transaction record files when the store is created. If you want to use the benefits of memory lock mechanism (2-5 times, depending on the transaction type), you need to change the owner of your app for root and give SET-User-ID permissions: chmod s Application.
Open memory
POST uses the memory memory mapping mechanism to access data in the file. Data consistency is provided in POST through two different ways. First, and more advanced is the mirror page used by the transaction mechanism, and the storage recovery and transaction rollback is provided later. Creating a calculation in front of the mirror page. This operation is performed in the following: All file mapping pages are set to read-only protection. Any write access to these pages will cause access violations. This exception is captured by a special handle. It changes the page protection to read and write and put this page copy in the transaction record file (record file name as the original file name, and then chasing ".log" combination). All the write operations of this page will no longer cause page errors. Memory Method Commit () refreshes all changing pages to disk and truncate log files. Storage :: commit () method is hidden by the Storage :: Close (). If the error occurs before the Storage :: Commit () operation, all changes will be restored by the page changed in the copy transaction record to the storage data file. Also all changes can be recovered by explicitly calling the Storage :: rollback () method. Select the mode based on the file access transaction by specifying the Storage :: Use_Transaction_log property of the Storage :: Open () method. Another means of providing data consistency is based on the write copy mechanism. In this case the source file is not affected. Any try to change the file mirror page, resulting in a copy of the page, which is allocated from the system exchange zone and has a read / write license. The file is updated until the Storage :: flush () method is explicitly invoked. This method writes data to temporary files (with suffix ".tmp") and renamed to its original. So this operation forms an atomic update (of course, assuming that the operating system ensures the number of atoms) of the rename ()).
Note: If you don't use the transaction, the Storage :: close () method will not brush data into the file. So if you call the Storage :: flush () method all the changes after the last FLUSH will be lost.
Windows 95 Details: Rename the existing file in Windows 95 is not, the source file is first saved as a file name with a suffix ".sav". Then the suffix ".tmp" temporary file is renamed to the original name and the last old copy is deleted. So if the error occurs in the flush () operation and then you can't find the storage file, please don't panic, just find the file ended with the income ".sav" and rename it to the original.
Tip: If you plan to save data during program execution, I strongly recommend that you use transaction. It is also possible to use a way to write a copy but this requires much more consumption. Also, if the storage is very large transaction processing, it is usually better because there is a lot of disk empty surfaces and time to generate a temporary file copy.
Here there are several attributes for storage Open () methods:
Support_virtual_functions
This property must be set if the objects in the memory belt with virtual functions. If this property is not set, Post assumes that all permanent objects contain only references (other objects in the memory) in the store. So only adjusting the reference only when changing the base address of the data file image (this address is stored in the first word of the data file and the post usually attempts to image files to the same address to avoid unnecessary reference adjustments). But if the object class contains the virtual function, the pointer to the virtual table is placed in the object. If you recompile your app, this deserial address may change. The POST library compares the timestamp of the object and the timestamp of the database generated by this application. If this timestamp does not wait, the pointer of the virtual table will be corrected. In order to get the application timestamp Post must be able to position the file object. Unfortunately, there is no easy way to perform the file name. At UNIX POST looks at the value of the environment variable "_" set by the command line interpreter. But if the process is not executed from the command line (such as via system ()) or work directory
CHDIR () changes this method will not work. The easiest way is to use files
Comptime.cxx, it must be compiled and linked to the repository each time you recompile your app. There is no such problem in Windows, the name of the image can be obtained by the Win32 API. POST compares this timestamp and data file when the memory is turned on, if they don't wait and specify
The Support_virtual_Functions property is corrected all objects (by calling the default constructor).
Read_only
By setting this property programmer, he only needs the data file read permissions. Post will create a read-only view of a data file and any attempt to change objects in the memory or a new object will result in protection against violations. Here is an exception: if the image data file is not imaged, it is specified when the application is changed or the application changes.
Support_virtual_functions, then the protection of this area is temporarily changed to a write copy and the loaded object is converted.
USE_TRANSACTION_LOG
Set this property to force all data files to update your transactions. The shadow page is used to perform a transaction. The transaction is opened after the first modification store. by
Storage :: Commit () or
Storage :: rollback () Operates explicitly close. method
Storage :: Commit () Save all changes to the disk and truncate transaction records, methods
Storage :: rollback () ignores all changes in this transaction.
NO_FILE_MAPPING
By default POST will image data files to process virtual memory. The time to open the database in this case will greatly decrease because the file page will be transferred when needed. However, if the database size is not particularly large or all data in the database needs to be accessed immediately, the file read is superior to the virtual memory image because there is no additional page overflow error in this case. Sign
NO_FILE_MAPPING blocks the POST image file and read files based on the assigned memory segment.
Fault_tolerant
This flag is used by the application to protect the consistency of the database in the system or application error. If you use a transaction
Use_transaction_log This flag does not have to be specified, as consistency can be provided by transaction mechanisms. If not specified
Use_transaction_log logo and set
The Fault_Tolerant flag, Post will not change the source file to maintain its consistency. This relies on reading files to memory (if not set)
NO_FILE_MAPPING logo or uses write copy page protection. In the latter case, try to change the page to files will result in generating page copies in the system exchange file.
The flush () method will save the image of the internal database into the temporary file and then rename the source file using the atomic operation. If you do not specify a Fault_Tolerant flag, Post is modified on the original location on the database page, providing maximum application performance (because there is no copy to modify the page and save the data image to the extra overhead of the database image). Some changes may be lost immediately under the condition that the modification page is refreshed, and some changes may be lost due to system errors (the worst thing is some modified by some modified pages, and there are other no saves - such the database may be disrupted).
Do_garbage_collection
POST will execute garbage collection when this property is turned on. Garbage collection operations are connected together. Using garbage collection is often safe than manual memory release (taken into account the suspended reference problem), but the explicit memory release is less. The garbage collection in Post has a greater advantage compared to explicit memory allocation: the memory collector optimizes the page used by the small object. If there is no assigned small object in the page, the garbage collector will contain this page in the idle page. This does not complete when explicitly released, because the idle unit of the small object is not simply removed from this chain (all chains in the garbage collector). Even if you use explicit memory release, I still recommend that you do garbage collection every other time to check the consistency and no memory leaks.
GARBAGE_COLLECTION method returns the number of free objects, if you are sure that you have released all the objects that you can't reach, then this value will be 0). Considering that the garbage collector modifies all objects (setting mask bits) in the storage, the idle objects in the reunal chain), running the GC in transaction mode may be a time consumption and disk space, because the page in all files will be Copy to the transaction record file).
You can specify the maximum size of the storage file via the file :: max_file_size variable. If the size of the data file is smaller than the file :: max_file_size and the mode is not read_only, the virtual space size_of_file - file :: max_file_size will be retained behind the file image space. These pages will be submitted (in Windows NT) when storage size extension (because new objects is assigned). If the file size is greater than File :: Max_File_Size or use the READ_ONLY mode, the size and file size of the image area are consistent. In the latter case, it is not possible to store expansion. In Windows I use the GlobalMemoryStatus () method to get information about the real-assignable virtual memory of the system and reduce file :: max_file_size is this value. Unfortunately I found that there is no light invision in UNIX to reach the same purpose (Gtrlimit does not return the exact information of virtual memory available to the user process).
The object stored interface is defined in file storage.h and the implementation section can be seen in Storage.cxx. The portion of the image memory file that relies on the operating system is encapsulated in the File class, which is defined in File.h implementation in File.cxx.
POST installation
POST installation is very simple. At present, the following systems have been tested: Digital UNIX, Linux, Solaris, Windows NT 4.0, Windows 95. I hope that there is no problem with most of all other new Unix dialects (AIX, HP-UX 10, SCO ...). Unfortunately, I didn't have used these systems. Under Windows I compiled using Microsoft Visual C 5.0 and Borland 5.02 Compilers. Visual C Makefiel is Makefile, Broland C Makefile is makefile. For the use of Post , what you need is the function library (under Unix is LibStorage.a under Windows is And Storage.LIB). This library can be generated by running the Make command. There is a special make.bater for Microsoft Visual C , which uses makefile.mvc as an input call NMAKE (if you are using Borland, edit this file or call it via make.exe -f makefile.bcc command).
The installation under UNIX can be done by copying the Post library and the same file to some standard system directories. You must set the appropriate value for the install_lib_path and install_inc_path variables in Makefile, and run the make install command. The default value of install_lib_path is / usr / local / lib install_inc_path is / usr / local / incrude. You can avoid copying files to the system directory by expressing the path to the POST directory.
POST class library
Post includes some persistent class definitions, they can be used for your applications as a good example of the development of Post classes. You can see that there are no Post-specific code in the implementation of those classes. These classes include Array (arrays), Matrix (Matrix), String (string), L2-List (L2-list), Hash Table, AVL-Tree (AVL-Tree), R-Tree (R - Number, Text Object. R-TREE provides quick access to providing spatial objects (objects containing space peers). The text object contains a correction of the Boyer and Moore algorithm, extends to a multi-style search by the or / and relationship. The definitions of these classes can be found in the following files:
Description interface Arrays of scalars and references, matrixes and stringsarray.harray.cxxL2-list and AVL-treeavltree.havltree.cxxHash table with collision chainshashtab.hhashab.cxxR-tree with quadratic method of nodes splittingrtree.hrtree.cxxT-tree (combination Of avl tree and array) Ttree.httree.cxxtExt Object with modified Boyer and Moore Search AlgorithmTextobj.htextobj.cxx
T. J. Lehman and m.j Carey is proposed using T-TREES as a stored valid data structure using T-TREES as a storage database. T-TREES is based on the AVL tree by ADELSON-VELSKY AND LANDIS. In this segment, we provide T-TREES an overview as an implementation in Post . Like the AVL tree, the height difference of the T-Tree's left subtree and the right subtree is not more than 1. Unlike the AVL tree, each node of T-Tree is arranged in order to save multiple key values instead of a single key value. The leftmost and rightmost key values in a node define the range of key values within this node. Thus, a node left sub-tree contains only a key value smaller than the leftmost key value, while the right child contains a key value larger than the rightmost key value of the node. The key value between the node in the minimum and maximum key values is referred to as the node constraint. Note that the keywords equal to the largest keyword or the smallest key can be considered to be constrained or not constrained according to the index. ("Greater-Than" ("greater-thank" is based on the index ("greater-thank") relative to "greater-Than" ("greater) -than or equal-to ")).
A node with both left subtroes also have the right sub-tree is classified as an internal node. There is only one node of a subtree being classified as a Semi-Leaf, a node without a sub-tree is returned to Leaf). In order to maintain a high occupancy, each internal node has a minimum of key values that must be included (typically k-2, if K is the maximum number of keywords that can be arranged in one node). However, there is no occupancy conditions for leaves and incomplete leaves.
Finding in T-TREE is equivalent to direct lookup. For each node, check if the key value is between the left and right key values; if this is the case, it returns this value if the key value in the node is (otherwise the key value is not included. In the tree. Otherwise, if the key value is smaller than the leftmost key value, then look for the left subtree, and see the right tree. Repeat this process until this key value is discovered or finds the NULL node.
Insert and delete in T-TREE is slightly more complex. For insertion operations, first use the above search procedure to find nodes inserted into the key value. If there is such a node, the noise key value in the node is inserted into this node. If there is no short, the key value is inserted into the node. The leftmost key value of the node is inserted into the left subtree of the node (if the left sub-tree is empty, allocate a new node to maximize the leftmost key Value inserted). If you do not find the constraint node, we use n to represent the last encountered node that the search failed and continued by the following steps: If the n is time, the key value is inserted into n; otherwise, the key value will be inserted into one The new node is based on the key value and the leftmost key value, and the rightmost key value as the right or left subtitle / tree.
Deleting a key value begins with a node containing a key value, and deletes a key value from the node. If you have an empty leaf junction after deleting the key value, the node is also deleted. If you remain in the delete or not fully leaf contains a key value than the minimum number, it will be supplemented by moving the largest key value in the left subtree to the node or merge nodes and the right subtree.
Regardless of the insertion or deletion, allocation / release nodes may cause the tree imbalance and rotation operation (RR, RL, LL, LR). (The height of the neutron tree includes the impact of insertion and deletion.) In the case of insertion, check the node along the new allocated node to the root node until a node has two contours of the subtree ( In this case, it is not necessary to rotate), or finding the left subtree and the right child of one node with a different height greater than 1 and execute a single rotation including the node.
In the case of deletion, check the node that begins to the hinden node along the parent of the release node until the height of the subtree tree is found. Moreover, each time the height of the subtree of a node is greater than 1, rotation is performed once. Note Releases a node that may result in multiple rotation.
There are several test programs to test classes in the Post persistent class library, they are included in the default Make target:
Programtested classestesttree.cxxavl-tree, l2-node, hash tabletesttext.cxxtext, stringtestspat.cxrectangle, r-tree, hash tabletestperf.cxxt-tree insert, Find and remove Operations
Use the STL class with Post
It is possible to save and get STL classes from the Post memory. POST provides special STL allocation and overloads the New / Delete operator to keep the STL object. There are a few models that make STL lasting models, through the following macro:
USE_MICROSOFT_STL
Use Microsoft STL classes to come with Microsoft Visual C . This class library and C STL standard are not fully compatible.
USE_STD_Allocators
Use the same distribution in the C standard. The assignment sub-objects are included in the STL object, and the instance method in the assignment sub-object is used to assign / release space. So it is possible to perform a "smart" allocation: the distribution sub-distribution space in the POST memory only in the case of the object contains this distribution sub-memory, and this distribution is also placed in the memory. Otherwise, the space occupied by the object will pass standards.
Malloc () function This normal path is assigned. This option can be used with the SGI STL library and the Microsoft STL library. Note that the compliance of the standard SGI STL allocation has used many language features that are not widely implemented. In particular, they rely on the Method template of member template, local specialization, partial classification (sort), Typename keyword, and template members that use the Template keyword to reference the dependent type. So only a few C compiler can compile the SGI STL library when specifying this macro definition. If this macro is not set, POST provides an allocation subsence subsequent subsidy with a static member function and all objects are allocated from the Post memory. Use this distribution sub-use only one POST memory can be opened at a time.
REDEFINE_DEFAULT_ALLOCATOR
There are two ways to make STL objects, and a way is to introduce new types:
Typedef Basic_String
Another way is to make all classes last. When defining the REDEFINE_DEFAULT_ALLOCATOR macro, any STL class can be assigned in the Post memory. In order to create a new object in a persistent memory, you must specify the memory as an additional parameter of the New operator. If the memory is ignored, the object will use the standard malloc () function. POST to STL interface does not require any STL class changes, so you can use any STL you want to do. However, as a result, the STL class does not include the type description, so Post does not have the format information of the STL object. So POST is not able to carry out garbage collection and reference alignment. When the STL interface is used, the Post memory must always mirror on the same virtual address. If you pass the Storage :: Fixed flag to the Storage :: Open (int flags) method, if you cannot mirror the memory to the same memory address POST , the report is wrong and returns false. If your application uses only one memory and mirror other objects into virtual memory, almost all operations may mirror memory to the same memory address.
The interface of the POST to the STL library is defined in the header file post_stl.h. This file must be included in any STL containment. The same macro REDEFINE_DEFAULT_ALLOCATOR, USE_STD_ALLOCATORS and USE_MICROSOFT_STL are defined before post_stl.h.
POST contains example stltest.cxx using the STL class. This example uses two STL classes - String and Vector. The lines read from the standard input are pressed into the vector and the program is once again launched to the standard output. This example is included in the default target of Makefile configured for Microsoft Visual C (which uses Microsoft STL classes included in the VC). You can also try to build this test with other versions of the STL library but don't forget about redine_default_allocator and use_std_allocators macros. This example can also be tested with SGI Stlport 3.12 and GCC 2.8.1.
Replace standard distribution
I explain how to use Post with the STL library. But there are still many other C and C libraries you want to use and the application, and no distribution mechanisms like STL. In this case, the only possible solution (if you don't want to change any source code of this library) is to replace standard allocation mechanisms with a Post . Such any dynamic allocation object is allocated from the POST memory (except for a memory that cannot be used in this case).
The files included in the Post release package redefine the standard Malloc, Free, Realloc, and Calloc functions. When the memory is turned on, all objects are allocated in the memory. Otherwise the SBRK () function is used to assign objects (there is no recycling for these objects allocated). You may not need to contact these standard C assignment functions and only need to overrunate the default C operator New and Delete. DO_NOT_REDEFINE_MALLOC macro is defined when compiling postnew.cxx. The target file generated from PostNew.cxx must be passed to the link before the standard C library.
Examples as a Post can see Testnew.cxx and TestQT.cxx. The first example illustrates how the standard C array persisted. The second example illustrates how Post works with the QT class library. There is no format information about the storage class. There are some limits to the use of Post :
The class containing virtual functions is not supported (POST does not initialize the pointer to the virtual function table). Implicit memory release (garbage collector) is impossible - post does not have information about the internal pointer position. Memory must always map to the same virtual address because the pointer cannot be adjusted if the base address changes POST .
If all of these restrictions are not required for your app, you can make it persisted without the changes of any code. This method can be used in C and C programs.
How to use Post
There are several examples of POST classes and applications here. The simplest is the game "guess animal". The algorithm of this game is very simple and the results seem to give people a deep impression (some like artificial intelligence). In addition, this game is a very good example, which clarifies the benefits of lasting object storage. The source code for this game is in the file guess.cxx. Creating this game is included in the default Make target. Execute Guess to run it.
UNIX Specific: When you are ready to link your UNIX app and your persistent object, you don't forget to compile the compaling compaling the comptime.cxx file and be included in the list. This file is a must-have timestamp for Post to provide executable files, which is placed in the memory to determine when applying changes and reinforcing the virtual function table within the object when needed. Attention! This file must be recompiled when you re-link your app. I suggest you let the compiler to call the linker and include the Comptime.cxx source file in the object file list provided for the running image target file (see makefile).
Debug the details of the POST application
The content of this section is very meaningful for the use of transactions. POST uses the page protection mechanism to generate the shadow page when the source page modification is to generate a shadow page, and the image of all file pages is read-only when the memory is turned on or transaction. So anything attempt to modify the contents of the objects allocated in these pages will result in an access violation exception. This exception is specified POST handle processing. But if you use the debugger, it will first capture this exception and stop the application. If you want to debug your app, you have to prepare:
In Unix, you can fully tell the debugger not to capture the SIGSEGV signal. For example, it can be done by commands: Handle Sigsegv Nostop Noprint Pass. If the SIGSEGV signal is not generated by the storage page, it is an error in the program. The Post exception handler will "understand" it is not its own anomalies and send a Sigabrt signal to the process, which can be captured by the debugger. Using the Windows Post Using the Unhandled Exception Filter to process the memory page protection violation. Unfortunately, it is impossible to let Microsoft Debugger ignore no exceptions. If you are ready to debug your app, you must package all your program code (Main or Winmain function) to structured exception blocking. You must use the structured exception handling in Borland C , because Unhandled Exception Filter is not called correctly in Borland. Please use two macro Sen_TRY and SEN_ACCESS_VIOLATION_HANDLER () to encapsulate main (or winmain) of the function body: main () {Sen_Try {
...
} SEN_ACCESS_VIOLATION_HANDLER ();
Return 0;
}
Please make sure the debugger is "if there is no processing" instead of "always stop" (you can check it in the Debug / Exceptions menu). In the file Testrans.cxx you can find examples of structured exception processing.
More information about Post
Post is freeware. Developing her hope is useful. With her you can do anything you want to do (there is no restrictions on using Post in development products). I will be very happy to help you use post and get information about POST any type (error report, suggestion ...). Free software in Post does not mean missing support. I guarantee that I will try to fix any report. E-mail support is also available. POST has several uses: Save information during different periods, save object systems, snapshots, information systems in the file ... but if you feel that you need to use more important object-oriented databases in your app to provide concurrency, distributed, and Transaction Processing, please visit Goods (Generic Object Oriented Database System) Home Page.
Look for new version at my homepage | E-mail me About bugs and problems