VersionedRandomAllocationSegment.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/segment/VersionedRandomAllocationSegment.h#14 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // Use a shared pointer because the structure is dynamically allocated.
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      * Locates data pages relevant to a backup or restore based on the
00570      * csn boundaries passed in, and then either backs up or restores the
00571      * pages identified.
00572      *
00573      * @param pBackupDevice device that carries out I/O for the backup or
00574      * restore
00575      * @param lowerBoundCsn the lower bound allocation csn
00576      * @param upperBoundCsn the upper bound allocation csn
00577      * @param isBackup if true, relevant pages are backed up; otherwise,
00578      * they are restored
00579      * @param [in] abortFlag reference to a flag indicating whether the backup
00580      * or restore should be aborted
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     // implement RandomAllocationSegmentBase
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     // implementation of Segment interface
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 // End VersionedRandomAllocationSegment.h

Generated on Mon Jun 22 04:00:20 2009 for Fennel by  doxygen 1.5.1