⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perst.html

📁 Perst开源实时数据库
💻 HTML
📖 第 1 页 / 共 5 页
字号:
In this case Perst will derive generated wrapper class from<code>Perst.Persistent</code> class (or from <code>Perst.PersistentResource</code> class if specified interface extends <code>Perst.IResource</code> interface).Wrapper class will implement specified interface and contains correspondent fields:<pre>class NodeWrapper:Persistent, Node {    public int Weight {        get {            return weight;        }        set {            weight = value;            Modify();        }    }    public Node Parent {        get {            return (Node)Storage.getByOid(parent);        }        set {            parent = value.MakePersistent(Storage);            Modify();        }    }}</pre>         In the second case you are using abstract class instead of interface:<pre>interface Node:Persistent {    public abstract int Weight {        get;        set;    }    public abstract Node Parent {         get;        set;    }}</pre>This class has to be derived from Persistent or PersistentResource class.There is only one difference in generated wrapper class - it extends specified abstract class:<pre>class NodeWrapper:Node {    ...}</pre><p>As far as there are not direct references between objects when this API is used, garbage collector will remove from memory all persistent objects which are not referencedfrom some program variables. That is why it is highly recommended to use LRU object cacheto increase performance (it is used by default).<p><code>PropGuess</code> example illustrates using of this Perst transparent API.<p><H2> <A NAME = "implementation">PERST implementation issues</A></H2>Below is more detailed description of PERST implementation.This section can be skipped if you are not interested in the details of implementation:<P><H3> <A NAME = "memory">Memory allocation</A></H3>Memory allocation is performed in PERST by bitmap. Memory is allocated inchunks called allocation quantum. In current version of PERST size ofallocation quantum is 64 byte. It means that size of all allocated objects isaligned on 64 byte boundary. Each 64 byte of database memory is represented byone bit in the bitmap. To locate hole of requested size in bitmap, PERSTsequentially searches bitmap pages for correspondent number of successivecleared bits. PERST use three arrays indexed by bitmap byte, whichmakes possible fast calculation of hole offset and size within the byte.<P>PERST performs cyclic scanning of bitmap pages. It keeps identifierof current bitmap page and current position within the page. Each timewhen allocation request arrives, scanning of the bitmap starts from thecurrent position.When last allocated bitmap page is scanned, scanning continues from thebeginning (from the first bitmap page) and until current position.When no free space is found after full cycle through all bitmap pages,new bulk of memory is allocated. Size of extension is maximum ofsize of allocated object and extension quantum. Extension quantum is parameterof database, specified in constructor. Bitmap is extended to be able to mapadditional space. If virtual space is exhausted and no morebitmap pages can be allocated, then <code>OutOfMemory</code> erroris reported.<P>Allocation memory using bitmap provides high locality of references(objects are mostly allocated sequentially) and also minimizesnumber of modified pages. Minimization of number of modified pages issignificant when commit operation is performed and all dirty pages shouldbe flushed on the disk. When all cloned objects are placed sequentially,number of modified pages is minimal and so transaction commit time is alsoreduced. Using extension quantum also helps topreserve sequential allocation. Once bitmap is extended, objects willbe allocated sequentially until extension quantum will be completely used.Only after reaching the end of the bitmap, scanning restarts from the beginningsearching for holes in previously allocated memory.<P>To reduce number of bitmap pages scans, PERST associates descriptor witheach page, which is used to remember maximal size of the hole on the page.Calculation of maximal hole size is performed in the following way:if object of size <I>M</I> can not be allocated from this bitmap pages,then maximal hole size is less than <I>M</I>, so <I>M</I>is stored in the page descriptor if previous value of descriptor is largethan <I>M</I>. For next allocation of object of size greater orequal than <I>M</I>, we will skip this bitmap page. Page descriptoris reset when some object is deallocated within this bitmap page.<P>Some database objects(like hash table pages) should be aligned on page boundaryto provide more efficient access. PERST memory  allocator checks requestedsize and if it is aligned on page boundary, then address ofallocated memory segment is also aligned on page boundary. Search of free holewill be done faster in this case, because PERST increases step of currentposition increment according to the value of alignment.<P>To be able to deallocate memory used by object, PERST needs to keepsomewhereinformation about object size. PERST memory allocator deals with two typesof objects - normal table records and page objects.All table records are prepended by record header, which containsrecord size and pointer of L2-list linking all records in the table.So size of the table record object can be extracted from record header.Page objects always occupies the whole database page are are allocated atthe positions aligned on page boundary. Page objects has no headers.PERST distinguish page objectswith normal object by using special marker in object index.<P><H3> <A NAME = "logless">Shadow transaction mechanism</A></H3>Each record (object) in PERST has unique identifier (OID).Object identifiersare used to implement references between objects. To locate object byreference, its OID is used as index in array of object offsets within the file.This array is called <I>object index</I> and element of this array -<I>object handle</I>. These are two copies of objectindices in PERST, one of which is current and other - shadow.Header of database contains pointers to both object indices and indicatorwhich index is current at this moment.<P>When object is modified first time, it is cloned(copy of the object is created) and object handle in current index ischanged to point to newly created object copy. And shadow index stillcontains handle which points to the original version of the object.All changes are done with the object copy, leaving original object unchanged.PERST marks in special bitmap page of the object index, which containsmodified object handle.<P>When transaction is committed, PERST first checks if size of object indexwas increased during current transaction. If so, it also reallocates shadowcopy of object index. Then PERST frees memory for all "old objects",i.e. objects which was cloned within transaction. Memory can not bedeallocated before commit, because we wants to preserve consistentstate of the database by keeping cloned object unchanged.If we deallocate memory immediately after cloning, new object can beallocated at the place of cloned object and we looseconsistency. As far as memory deallocation is done in PERST by bitmapusing the same transaction mechanism as for normal database objects,deallocation of object space will require clearing some bits in bitmap page,which also should be cloned before modification. Cloning bitmap page willrequire new space for allocation the page copy, and we can reuse space ofdeallocated objects. And it is not acceptable due to the reason explainedabove - we will loose database consistency. That is why deallocationof object is done in two steps. When object is cloned, all bitmap pagesused for marking objects space, are also cloned (if notnot cloned before). So when transaction is committed, we only clear bits inbitmap pages and no more requests for allocation memory can be generated atthis moment.<P>After deallocation of old copies, PERST flushes all modified pages on diskto synchronize content of the memory and disk file. After that PERSTchanges current object index indicator in databaseheader to switch roles of the object indices. Now object index, which wascurrent becomes shadow, and shadow index becomes current. Then PERST againflushes modified page (i.e. page with database header) on disk, transferringdatabase to new consistent state.After that PERST copies all modified handles from new object indexto object index which was previously shadow and now becomes current.At this moment contents of both indices is synchronized and PERST is readyto start new transaction.<P>Bitmap of modified object index pages is used to minimize time of committingtransaction. Not the whole object index, but only its modified pages should becopied. After committing of transaction bitmap is cleared.<P>When transaction is explicitly aborted by <code>Storage.rollback</code>method, shadow object index is copied back to the current index, eliminatingall changes done by aborted transaction. After the end of copying,both indices are identical again and database state corresponds to the momentbefore the start of current transaction.<P>Allocation of object handles is done by free handles list. Header of the listis also shadowed and two instances of list headers are stored in databaseheader. Switch between them is done in the same way as switch ofobject indices. When there are no more free elements in the list, PERSTallocates handles from the unused part of new index. When there is nomore space in the index, it is reallocated. Object index is the onlyentity in database whose is not cloned on modification. Instead of thistwo copies of object index are always used.<P>There are some predefined OID values in PERST. OID <I>0</I> is reservedas invalid object identifier. OID starting from <I>1</I> are reserved for bitmap pages.Number of bitmap pages depends on database maximum virtual space.For one terabyte virtual space, 8 Kb page size and 64 byte allocation quantum,32K bitmap pages are required. So 32K handles are reserved in object index forbitmap. Bitmap pages are allocated on demand, when database size is extended.So OID of first users object will be 0x8002.<P>Recovery procedure is trivial in PERST. There are two instances ofobject index, one of which is current and another corresponds toconsistent database state. When database is opened, PERST checks databaseheader to detect if database was normally closed. If not(<code>dirty</code> flag is set in database header), then PERST performsdatabase recovery. Recovery is very similar to rollback of transaction.Indicator of current index in database object header is used todetermine index corresponding to consistent database state and object handlesfrom this index are copied to another object index, eliminatingall changes done by uncommitted transaction. As far as the only actionperformed by recovery procedure is copying of objects index (really onlyhandles having different values in current and shadow indices are copied toreduce number of modified pages) and size of object index is small,recovery can be done very fast.Fast recovery procedure reduces "out-of-service" time of application.<P><H2> <A NAME = "where">Where to use</A></H2>PERST is simple and fast embedded database engine. If your applications need embedded database engine and do not need to execute complex SQL queries, and the only thing you need is to be able to store/fetch/locate object in the database using navigation through references or indexed search by key, then PERST is what you need. It will provide much better performancethan relational database and other (more sophisticated) object oriented database.<P>The table below summarize <B>pro</B> features of PERST:<P><OL><LI>Tight and transparent integration with programming language<LI>No gap in database and application data model<LI>Easy to use<LI>Minimal requirements (PERST package itself has size only 51Kb and it can be configured to use minimal memory and diskspace during it

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -