LinearDeviceSegment.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/segment/LinearDeviceSegment.cpp#11 $
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 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/segment/LinearDeviceSegment.h"
00026 #include "fennel/device/RandomAccessDevice.h"
00027 #include "fennel/cache/Cache.h"
00028 
00029 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/segment/LinearDeviceSegment.cpp#11 $");
00030 
00031 LinearDeviceSegmentParams::LinearDeviceSegmentParams()
00032 {
00033     firstBlockId = NULL_BLOCK_ID;
00034     nPagesMin = 0;
00035     nPagesAllocated = 0;
00036     nPagesIncrement = 1;
00037     nPagesMax = MAXU;
00038 }
00039 
00040 BlockNum LinearDeviceSegment::getAvailableDevicePages() const
00041 {
00042     return pDevice->getSizeInBytes() / getFullPageSize() -
00043         CompoundId::getBlockNum(firstBlockId);
00044 }
00045 
00046 LinearDeviceSegment::LinearDeviceSegment(
00047     SharedCache cache,
00048     LinearDeviceSegmentParams const &params)
00049     : Segment(cache),
00050       pDevice(
00051           cache->getDevice(CompoundId::getDeviceId(params.firstBlockId)))
00052 {
00053     firstBlockId = params.firstBlockId;
00054     nPagesMax = params.nPagesMax;
00055     nPagesAllocated = params.nPagesAllocated;
00056     nPagesIncrement = params.nPagesIncrement;
00057     nPagesExtended = 0;
00058     BlockNum nPagesActual = getAvailableDevicePages();
00059     if (nPagesActual < params.nPagesMin) {
00060         pDevice->setSizeInBytes(
00061             pDevice->getSizeInBytes() +
00062             (params.nPagesMin - nPagesActual)*getFullPageSize());
00063         nPagesActual = params.nPagesMin;
00064     }
00065     if (isMAXU(nPagesAllocated)) {
00066         nPagesAllocated = nPagesActual;
00067     } else {
00068         assert(nPagesAllocated <= nPagesActual);
00069     }
00070 }
00071 
00072 LinearDeviceSegment::~LinearDeviceSegment()
00073 {
00074 }
00075 
00076 BlockId LinearDeviceSegment::translatePageId(PageId pageId)
00077 {
00078     assert(isPageIdAllocated(pageId));
00079     BlockId blockId = firstBlockId;
00080     CompoundId::setBlockNum(
00081         blockId,
00082         CompoundId::getBlockNum(firstBlockId)
00083         + getLinearBlockNum(pageId));
00084     return blockId;
00085 }
00086 
00087 PageId LinearDeviceSegment::translateBlockId(BlockId blockId)
00088 {
00089     return getLinearPageId(
00090         CompoundId::getBlockNum(blockId)
00091         - CompoundId::getBlockNum(firstBlockId));
00092 }
00093 
00094 BlockNum LinearDeviceSegment::getAllocatedSizeInPages()
00095 {
00096     return nPagesAllocated;
00097 }
00098 
00099 BlockNum LinearDeviceSegment::getNumPagesOccupiedHighWater()
00100 {
00101     return getAllocatedSizeInPages();
00102 }
00103 
00104 BlockNum LinearDeviceSegment::getNumPagesExtended()
00105 {
00106     return nPagesExtended;
00107 }
00108 
00109 PageId LinearDeviceSegment::allocatePageId(PageOwnerId)
00110 {
00111     // nothing to do with PageOwnerId
00112 
00113     BlockNum newBlockNum = nPagesAllocated;
00114 
00115     if (!ensureAllocatedSize(nPagesAllocated + 1)) {
00116         return NULL_PAGE_ID;
00117     }
00118 
00119     return getLinearPageId(newBlockNum);
00120 }
00121 
00122 void LinearDeviceSegment::deallocatePageRange(
00123     PageId startPageId,PageId endPageId)
00124 {
00125     if (endPageId != NULL_PAGE_ID) {
00126         // REVIEW:  Technically, this should assert; instead, we let it slip so
00127         // that LinearDeviceSegments can be used as really stupid logs in
00128         // tests.  Should probably fix the tests and tighten this up.
00129         return;
00130     }
00131     if (startPageId == NULL_PAGE_ID) {
00132         nPagesAllocated = 0;
00133     } else {
00134         nPagesAllocated = getLinearBlockNum(startPageId);
00135     }
00136 }
00137 
00138 bool LinearDeviceSegment::isPageIdAllocated(PageId pageId)
00139 {
00140     return isLinearPageIdAllocated(pageId);
00141 }
00142 
00143 PageId LinearDeviceSegment::getPageSuccessor(PageId pageId)
00144 {
00145     return getLinearPageSuccessor(pageId);
00146 }
00147 
00148 void LinearDeviceSegment::setPageSuccessor(PageId pageId,PageId successorId)
00149 {
00150     setLinearPageSuccessor(pageId,successorId);
00151 }
00152 
00153 Segment::AllocationOrder LinearDeviceSegment::getAllocationOrder() const
00154 {
00155     return LINEAR_ALLOCATION;
00156 }
00157 
00158 DeviceId LinearDeviceSegment::getDeviceId() const
00159 {
00160     return CompoundId::getDeviceId(firstBlockId);
00161 }
00162 
00163 bool LinearDeviceSegment::ensureAllocatedSize(BlockNum nPages)
00164 {
00165     if (nPages > nPagesMax) {
00166         return false;
00167     }
00168     if (nPages <= nPagesAllocated) {
00169         return true;
00170     }
00171     BlockNum nPagesAvailable = getAvailableDevicePages();
00172     assert(nPagesAllocated <= nPagesAvailable);
00173     if (nPages > nPagesAvailable) {
00174         if (!nPagesIncrement) {
00175             return false;
00176         }
00177         BlockNum nNewPages = std::max(nPagesIncrement,nPages - nPagesAvailable);
00178         if (!isMAXU(nPagesMax) && (nPagesAvailable + nNewPages > nPagesMax)) {
00179             nNewPages = nPagesMax - nPagesAvailable;
00180         }
00181         assert(nNewPages);
00182         nPagesExtended += nNewPages;
00183         pDevice->setSizeInBytes(
00184             pDevice->getSizeInBytes() + nNewPages*getFullPageSize());
00185     }
00186     nPagesAllocated = nPages;
00187     return true;
00188 }
00189 
00190 void LinearDeviceSegment::delegatedCheckpoint(
00191     Segment &delegatingSegment,
00192     CheckpointType checkpointType)
00193 {
00194     Segment::delegatedCheckpoint(delegatingSegment,checkpointType);
00195     if (checkpointType != CHECKPOINT_DISCARD) {
00196         pDevice->flush();
00197     }
00198 }
00199 
00200 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/segment/LinearDeviceSegment.cpp#11 $");
00201 
00202 // End LinearDeviceSegment.cpp

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