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