00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef Fennel_VersionedRandomAllocationSegment_Included
00025 #define Fennel_VersionedRandomAllocationSegment_Included
00026 
00027 #include "fennel/synch/SXMutex.h"
00028 #include "fennel/segment/RandomAllocationSegmentBase.h"
00029 #include "fennel/segment/SegPageBackupRestoreDevice.h"
00030 
00031 #include <hash_set>
00032 #include <hash_map>
00033 #include <boost/shared_ptr.hpp>
00034 
00035 FENNEL_BEGIN_NAMESPACE
00036 
00037 struct VersionedExtentAllocationNode;
00038 struct ModifiedAllocationNode;
00039 
00040 typedef boost::shared_ptr<ModifiedAllocationNode> SharedModifiedAllocationNode;
00041 
00045 struct FENNEL_SEGMENT_EXPORT VersionedPageEntry
00046     : PageEntry
00047 {
00052     TxnId allocationCsn;
00053 
00057     PageId versionChainPageId;
00058 };
00059 
00065 struct FENNEL_SEGMENT_EXPORT ModifiedPageEntry
00066 {
00067     enum ModType {
00068         ALLOCATED,
00069         DEALLOCATED,
00070         MODIFIED
00071     };
00072 
00077     uint updateCount;
00078 
00083     uint allocationCount;
00084 
00090     ModType lastModType;
00091 
00096     PageOwnerId ownerId;
00097 };
00098 
00099 typedef boost::shared_ptr<ModifiedPageEntry> SharedModifiedPageEntry;
00100 
00101 
00102 typedef std::hash_map<PageId, SharedModifiedPageEntry> ModifiedPageEntryMap;
00103 typedef ModifiedPageEntryMap::const_iterator ModifiedPageEntryMapIter;
00104 
00108 static const PageOwnerId UNCOMMITTED_PAGE_OWNER_ID = PageOwnerId(1);
00109 
00116 static const uint64_t DEALLOCATED_PAGE_OWNER_ID_MASK = 0x8000000000000000LL;
00117 
00138 class FENNEL_SEGMENT_EXPORT VersionedRandomAllocationSegment
00139     : public RandomAllocationSegmentBase
00140 {
00141     typedef std::hash_map<PageId, SharedModifiedAllocationNode>
00142         ModifiedAllocationNodeMap;
00143 
00144     typedef ModifiedAllocationNodeMap::const_iterator NodeMapConstIter;
00145 
00150     ModifiedAllocationNodeMap allocationNodeMap;
00151 
00159     SXMutex mapMutex;
00160 
00167     SXMutex deallocationMutex;
00168 
00173     SharedSegment pTempSegment;
00174 
00190     template <class AllocationLockT>
00191     PageId getTempAllocNodePage(PageId origNodePageId, bool isSegAllocNode);
00192 
00209     PageId findAllocPageIdForRead(
00210         PageId origAllocNodePageId,
00211         SharedSegment &allocNodeSegment);
00212 
00220     void deferDeallocation(PageId pageId);
00221 
00244     void updateExtentEntry(
00245         uint iSegAlloc,
00246         ExtentNum extentNum,
00247         uint allocationCount,
00248         bool commit);
00249 
00264     void allocateAllocNodes(
00265         uint iSegAlloc,
00266         PageId nextPageId,
00267         ExtentNum extentNum);
00268 
00283     void allocateExtAllocNodes(
00284         SegmentAllocationNode &segAllocNode,
00285         uint iSegAlloc,
00286         ExtentNum extentNum);
00287 
00314     void updatePageEntry(
00315         PageId pageId,
00316         ExtentNum extentNum,
00317         uint iPageInExtent,
00318         SharedModifiedPageEntry pModEntry,
00319         TxnId commitCsn,
00320         bool commit,
00321         SharedSegment pOrigSegment);
00322 
00341     void copyPageEntryFromTemp(
00342         PageId pageId,
00343         PageId origPageId,
00344         PageId tempPageId,
00345         BlockNum iPageInExtent,
00346         ModifiedPageEntry::ModType lastModType,
00347         TxnId commitCsn,
00348         PageOwnerId ownerId);
00349 
00359     void copyPageEntryToTemp(
00360         PageId origPageId,
00361         PageId tempPageId,
00362         BlockNum iPageInExtent);
00363 
00374     bool validateFreePageCount(PageId pageId);
00375 
00389     void freeTempPage(PageId origAllocNodePageId, PageId tempAllocNodePageId);
00390 
00417     TxnId getOldestTxnId(
00418         PageId pageId,
00419         TxnId oldestActiveTxnId,
00420         PageId &anchorPageId,
00421         std::hash_set<PageId> &deallocatedPageSet,
00422         bool &deallocateChain);
00423 
00435     void deallocateEntirePageChain(
00436         PageId pageId,
00437         TxnId oldestActiveTxnId,
00438         std::hash_set<PageId> &deallocatedPageSet);
00439 
00450     void deallocateSinglePage(
00451         PageId pageId,
00452         std::hash_set<PageId> &deallocatedPageSet);
00453 
00465     void deallocatePageChain(
00466         PageId anchorPageId,
00467         TxnId deallocationCsn,
00468         std::hash_set<PageId> &deallocatedPageSet);
00469 
00478     bool validatePageChain(PageId anchorPageId);
00479 
00495     bool uncommittedDeallocation(
00496         PageId anchorPageId,
00497         std::hash_set<PageId> &deallocatedPageSet);
00498 
00509     void skipDeferredDeallocations(
00510         PageId pageId,
00511         std::hash_set<PageId> &deallocatedPageSet);
00512 
00523     void updateTempPageEntry(
00524         PageId pageId,
00525         VersionedPageEntry const &pageEntry);
00526 
00534     void getCommittedPageEntryCopy(
00535         PageId pageId,
00536         VersionedPageEntry &pageEntryCopy);
00537 
00543     bool isPageIdAllocateCommitted(PageId pageId);
00544 
00562     void chainPageEntries(
00563         PageId pageId,
00564         PageId versionChainId,
00565         PageId successorId,
00566         bool thisSegment);
00567 
00568     
00569 
00570 
00571 
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582     void locateDataPages(
00583         SharedSegPageBackupRestoreDevice pBackupDevice,
00584         TxnId lowerBoundCsn,
00585         TxnId upperBoundCsn,
00586         bool isBackup,
00587         bool volatile const &abortFlag);
00588 
00595     void checkAbort(bool volatile const &abortFlag);
00596 
00604     inline PageOwnerId makeDeallocatedPageOwnerId(TxnId txnId);
00605 
00615     inline bool isDeallocatedPageOwnerId(PageOwnerId pageOwnerId);
00616 
00625     inline TxnId getDeallocatedTxnId(PageOwnerId pageOwnerId);
00626 
00627     
00628     virtual bool isPageIdValid(PageId pageId);
00629     virtual PageId getSegAllocPageIdForWrite(PageId origSegAllocPageId);
00630     virtual void undoSegAllocPageWrite(PageId segAllocPageId);
00631     virtual PageId getExtAllocPageIdForWrite(ExtentNum extentNum);
00632     virtual PageId allocateFromExtent(ExtentNum extentNum, PageOwnerId ownerId);
00633     virtual void formatPageExtents(
00634         SegmentAllocationNode &segAllocNode,
00635         ExtentNum &extentNum);
00636     virtual PageId allocateFromNewExtent(
00637         ExtentNum extentNum,
00638         PageOwnerId ownerId);
00639     virtual void freePageEntry(ExtentNum extentNum, BlockNum iPageInExtent);
00640     virtual void markPageEntryUnused(PageEntry &pageEntry);
00641     virtual PageOwnerId getPageOwnerId(PageId pageId, bool thisSegment);
00642     virtual PageId getSegAllocPageIdForRead(
00643         PageId origSegAllocPageId,
00644         SharedSegment &allocNodeSegment);
00645     virtual PageId getExtAllocPageIdForRead(
00646         ExtentNum extentNum,
00647         SharedSegment &allocNodeSegment);
00648     virtual void getPageEntryCopy(
00649         PageId pageId,
00650         PageEntry &pageEntryCopy,
00651         bool isAllocated,
00652         bool thisSegment);
00653 
00654 public:
00655     explicit VersionedRandomAllocationSegment(
00656         SharedSegment delegateSegment,
00657         SharedSegment pTempSegmentInit);
00658 
00667     void getLatestPageEntryCopy(
00668         PageId pageId,
00669         VersionedPageEntry &pageEntryCopy);
00670 
00680     void initPageEntry(
00681         PageId pageId,
00682         PageId versionChainId,
00683         TxnId allocationCsn);
00684 
00699     void chainPageEntries(
00700         PageId pageId,
00701         PageId versionChainId,
00702         PageId successorId);
00703 
00721     void updateAllocNodes(
00722         ModifiedPageEntryMap const &modifiedPageEntryMap,
00723         TxnId commitCsn,
00724         bool commit,
00725         SharedSegment pOrigSegment);
00726 
00731     SXMutex &getDeallocationMutex();
00732 
00769     bool getOldPageIds(
00770         uint &iSegAlloc,
00771         ExtentNum &extentNum,
00772         TxnId oldestActiveTxnId,
00773         uint numPages,
00774         PageSet &oldPageSet);
00775 
00789     void deallocateOldPages(PageSet const &oldPageSet, TxnId oldestActiveTxnId);
00790 
00797     void freeTempPages();
00798 
00819     BlockNum backupAllocationNodes(
00820         SharedSegPageBackupRestoreDevice pBackupDevice,
00821         bool countDataPages,
00822         TxnId lowerBoundCsn,
00823         TxnId upperBoundCsn,
00824         bool volatile const &abortFlag);
00825 
00839     void backupDataPages(
00840         SharedSegPageBackupRestoreDevice pBackupDevice,
00841         TxnId lowerBoundCsn,
00842         TxnId upperBoundCsn,
00843         bool volatile const &abortFlag);
00844 
00859     void restoreFromBackup(
00860         SharedSegPageBackupRestoreDevice pBackupDevice,
00861         TxnId lowerBoundCsn,
00862         TxnId upperBoundCsn,
00863         bool volatile const &abortFlag);
00864 
00865     
00866     virtual bool isPageIdAllocated(PageId pageId);
00867     virtual PageId allocatePageId(PageOwnerId ownerId);
00868     virtual PageId getPageSuccessor(PageId pageId);
00869     virtual void setPageSuccessor(PageId pageId, PageId successorId);
00870     virtual void deallocatePageRange(PageId startPageId, PageId endPageId);
00871     virtual void initForUse();
00872 };
00873 
00874 FENNEL_END_NAMESPACE
00875 
00876 #endif
00877 
00878