SegmentFactory.cpp

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/segment/SegmentFactory.cpp#19 $
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/SegmentFactory.h"
00026 #include "fennel/segment/LinearDeviceSegment.h"
00027 #include "fennel/segment/LinearViewSegment.h"
00028 #include "fennel/segment/WALSegment.h"
00029 #include "fennel/segment/VersionedSegment.h"
00030 #include "fennel/segment/ScratchSegment.h"
00031 #include "fennel/segment/RandomAllocationSegment.h"
00032 #include "fennel/segment/SnapshotRandomAllocationSegment.h"
00033 #include "fennel/segment/VersionedRandomAllocationSegment.h"
00034 #include "fennel/segment/DynamicDelegatingSegment.h"
00035 #include "fennel/segment/CircularSegment.h"
00036 #include "fennel/segment/SegmentAccessor.h"
00037 #include "fennel/common/ConfigMap.h"
00038 #include "fennel/common/FileSystem.h"
00039 #include "fennel/device/RandomAccessFileDevice.h"
00040 
00041 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/segment/SegmentFactory.cpp#19 $");
00042 
00043 ParamName SegmentFactory::paramTraceSegments = "traceSegments";
00044 
00045 SharedSegmentFactory SegmentFactory::newSegmentFactory(
00046     ConfigMap const &configMap,
00047     SharedTraceTarget pTraceTarget)
00048 {
00049     return SharedSegmentFactory(
00050         new SegmentFactory(configMap,pTraceTarget));
00051 }
00052 
00053 SegmentFactory::SegmentFactory(
00054     ConfigMap const &configMapInit,
00055     SharedTraceTarget pTraceTargetInit)
00056     : configMap(configMapInit)
00057 {
00058     pTraceTarget = pTraceTargetInit;
00059 
00060     // TODO:  parameterize
00061     firstTempDeviceId = DeviceId(512);
00062     tempDeviceIdBitset.resize(512);
00063 }
00064 
00065 SegmentFactory::~SegmentFactory()
00066 {
00067 }
00068 
00069 ConfigMap const &SegmentFactory::getConfigMap() const
00070 {
00071     return configMap;
00072 }
00073 
00074 SharedSegment SegmentFactory::newLinearDeviceSegment(
00075     SharedCache cache,
00076     LinearDeviceSegmentParams const &params)
00077 {
00078     SharedSegment pSegment(
00079         new LinearDeviceSegment(cache,params),
00080         ClosableObjectDestructor());
00081     SharedSegment tracingSegment =
00082         newTracingSegment(pSegment,"LinearDeviceSegment");
00083     tracingSegment->initForUse();
00084     return tracingSegment;
00085 }
00086 
00087 SharedSegment SegmentFactory::newRandomAllocationSegment(
00088     SharedSegment delegateSegment,
00089     bool bFormat,
00090     bool deferInit)
00091 {
00092     RandomAllocationSegment *pRandomSegment =
00093         new RandomAllocationSegment(delegateSegment);
00094     SharedSegment pSegment(pRandomSegment,ClosableObjectDestructor());
00095     SharedSegment tracingSegment =
00096         newTracingSegment(pSegment,"RandomAllocationSegment");
00097     // Format the segment through the tracing segment so the operation
00098     // is traced
00099     if (bFormat) {
00100         tracingSegment->deallocatePageRange(NULL_PAGE_ID,NULL_PAGE_ID);
00101     }
00102     if (!deferInit) {
00103         tracingSegment->initForUse();
00104     }
00105     return tracingSegment;
00106 }
00107 
00108 SharedSegment SegmentFactory::newVersionedRandomAllocationSegment(
00109     SharedSegment delegateSegment,
00110     SharedSegment pTempSegment,
00111     bool bFormat,
00112     bool deferInit)
00113 {
00114     VersionedRandomAllocationSegment *pVersionedRandomSegment =
00115         new VersionedRandomAllocationSegment(delegateSegment, pTempSegment);
00116     SharedSegment pSegment(pVersionedRandomSegment, ClosableObjectDestructor());
00117     SharedSegment tracingSegment =
00118         newTracingSegment(pSegment, "VersionedRandomAllocationSegment");
00119     // Format the segment through the tracing segment so the operation
00120     // is traced
00121     if (bFormat) {
00122         tracingSegment->deallocatePageRange(NULL_PAGE_ID, NULL_PAGE_ID);
00123     }
00124     if (!deferInit) {
00125         tracingSegment->initForUse();
00126     }
00127     return tracingSegment;
00128 }
00129 
00130 SharedSegment SegmentFactory::newSnapshotRandomAllocationSegment(
00131     SharedSegment delegateSegment,
00132     SharedSegment versionedSegment,
00133     TxnId snapshotCsn,
00134     bool readOnlyCommittedData)
00135 {
00136     SnapshotRandomAllocationSegment *pSnapshotSegment =
00137         new SnapshotRandomAllocationSegment(
00138             delegateSegment,
00139             versionedSegment,
00140             snapshotCsn,
00141             readOnlyCommittedData);
00142     SharedSegment pSegment(pSnapshotSegment, ClosableObjectDestructor());
00143     SharedSegment tracingSegment =
00144         newTracingSegment(pSegment, "SnapshotRandomAllocationSegment");
00145     tracingSegment->initForUse();
00146     return tracingSegment;
00147 }
00148 
00149 SharedSegment SegmentFactory::newDynamicDelegatingSegment(
00150     SharedSegment delegateSegment)
00151 {
00152     DynamicDelegatingSegment *pDelegatingSegment =
00153         new DynamicDelegatingSegment(WeakSegment(delegateSegment));
00154     SharedSegment pSegment(pDelegatingSegment, ClosableObjectDestructor());
00155     SharedSegment tracingSegment =
00156         newTracingSegment(pSegment, "DynamicDelegatingSegment");
00157     tracingSegment->initForUse();
00158     return tracingSegment;
00159 }
00160 
00161 SharedSegment SegmentFactory::newWALSegment(
00162     SharedSegment logSegment)
00163 {
00164     SharedSegment pSegment(
00165         new WALSegment(logSegment),
00166         ClosableObjectDestructor());
00167     SharedSegment tracingSegment =
00168         newTracingSegment(pSegment,"WALSegment");
00169     tracingSegment->initForUse();
00170     return tracingSegment;
00171 }
00172 
00173 SharedSegment SegmentFactory::newLinearViewSegment(
00174     SharedSegment delegateSegment,
00175     PageId firstPageId)
00176 {
00177     SharedSegment pSegment(
00178         new LinearViewSegment(delegateSegment,firstPageId),
00179         ClosableObjectDestructor());
00180     SharedSegment tracingSegment =
00181         newTracingSegment(pSegment,"LinearViewSegment");
00182     tracingSegment->initForUse();
00183     return tracingSegment;
00184 }
00185 
00186 SharedSegment SegmentFactory::newVersionedSegment(
00187     SharedSegment dataSegment,
00188     SharedSegment logSegment,
00189     PseudoUuid const &onlineUuid,
00190     SegVersionNum versionNumber)
00191 {
00192     SharedSegment pSegment(
00193         new VersionedSegment(dataSegment,logSegment,onlineUuid,versionNumber),
00194         ClosableObjectDestructor());
00195     SharedSegment tracingSegment =
00196         newTracingSegment(pSegment,"VersionedSegment");
00197     tracingSegment->initForUse();
00198     return tracingSegment;
00199 }
00200 
00201 SegmentAccessor SegmentFactory::newScratchSegment(
00202     SharedCache pCache,
00203     uint nPagesMax)
00204 {
00205     boost::shared_ptr<ScratchSegment> pSegment(
00206         new ScratchSegment(pCache,nPagesMax),
00207         ClosableObjectDestructor());
00208     SegmentAccessor segmentAccessor;
00209     segmentAccessor.pSegment = newTracingSegment(pSegment,"ScratchSegment");
00210     segmentAccessor.pSegment->initForUse();
00211     segmentAccessor.pCacheAccessor = pSegment;
00212     return segmentAccessor;
00213 }
00214 
00215 SharedSegment SegmentFactory::newCircularSegment(
00216     SharedSegment delegateSegment,
00217     SharedCheckpointProvider pCheckpointProvider,
00218     PageId oldestPageId,
00219     PageId newestPageId)
00220 {
00221     SharedSegment pSegment(
00222         new CircularSegment(
00223             delegateSegment,
00224             pCheckpointProvider,
00225             oldestPageId,newestPageId),
00226         ClosableObjectDestructor());
00227     SharedSegment tracingSegment =
00228         newTracingSegment(pSegment,"CircularSegment");
00229     tracingSegment->initForUse();
00230     return tracingSegment;
00231 }
00232 
00233 SharedSegment SegmentFactory::newTracingSegment(
00234     SharedSegment pSegment,
00235     std::string sourceName,
00236     bool qualifySourceName)
00237 {
00238     if (!pTraceTarget.get()) {
00239         return pSegment;
00240     }
00241     if (qualifySourceName) {
00242         std::ostringstream oss;
00243         oss << "segment." << sourceName << "." << pSegment.get();
00244         sourceName = oss.str();
00245     }
00246     if (pTraceTarget->getSourceTraceLevel(sourceName) > TRACE_FINE) {
00247         // all segment tracing is TRACE_FINE or lower, so don't bother
00248         return pSegment;
00249     }
00250     SharedSegment pTracingSegment(
00251         new TracingSegment(pSegment,pTraceTarget,sourceName),
00252         ClosableObjectDestructor());
00253 
00254     pSegment->setTracingSegment(WeakSegment(pTracingSegment));
00255 
00256     return pTracingSegment;
00257 }
00258 
00259 // TODO:  parameters
00260 SharedSegment SegmentFactory::newTempDeviceSegment(
00261     SharedCache pCache,
00262     DeviceMode deviceMode,
00263     std::string deviceFileName)
00264 {
00265     // TODO:  guard to automatically deallocateTempDeviceId on failure?
00266     DeviceId deviceId = allocateTempDeviceId();
00267     if (deviceMode.create) {
00268         FileSystem::remove(deviceFileName.c_str());
00269     }
00270     // TODO: depending on config params?
00271     // deviceMode.temporary = true;
00272     SharedRandomAccessDevice pDevice(
00273         new RandomAccessFileDevice(deviceFileName,deviceMode));
00274     pCache->registerDevice(deviceId,pDevice);
00275     LinearDeviceSegmentParams deviceParams;
00276     CompoundId::setDeviceId(deviceParams.firstBlockId,deviceId);
00277     CompoundId::setBlockNum(deviceParams.firstBlockId,0);
00278     deviceParams.nPagesAllocated = 0;
00279     if (!deviceMode.create) {
00280         deviceParams.nPagesAllocated = MAXU;
00281     }
00282     SharedSegment pSegment(
00283         new LinearDeviceSegment(pCache,deviceParams),
00284         TempSegDestructor(shared_from_this()));
00285     SharedSegment tracingSegment =
00286         newTracingSegment(pSegment,"TempLinearDeviceSegment");
00287     tracingSegment->initForUse();
00288     return tracingSegment;
00289 }
00290 
00291 DeviceId SegmentFactory::allocateTempDeviceId()
00292 {
00293     StrictMutexGuard mutexGuard(mutex);
00294     // TODO:  submit fast find-clear-bit to boost
00295     for (uint i = 0; i < tempDeviceIdBitset.size(); ++i) {
00296         if (!tempDeviceIdBitset[i]) {
00297             tempDeviceIdBitset[i] = true;
00298             return firstTempDeviceId + i;
00299         }
00300     }
00301     permAssert(false);
00302 }
00303 
00304 void SegmentFactory::deallocateTempDeviceId(DeviceId deviceId)
00305 {
00306     StrictMutexGuard mutexGuard(mutex);
00307     uint i = opaqueToInt(deviceId - firstTempDeviceId);
00308     assert(tempDeviceIdBitset[i]);
00309     tempDeviceIdBitset[i] = false;
00310 }
00311 
00312 TempSegDestructor::TempSegDestructor(
00313     SharedSegmentFactory pSegmentFactoryInit)
00314     : pSegmentFactory(pSegmentFactoryInit)
00315 {
00316 }
00317 
00318 void TempSegDestructor::operator()(Segment *pSegment)
00319 {
00320     LinearDeviceSegment *pLinearDeviceSegment =
00321         dynamic_cast<LinearDeviceSegment *>(pSegment);
00322     SharedCache pCache = pSegment->getCache();
00323     DeviceId deviceId = pLinearDeviceSegment->getDeviceId();
00324     // NOTE:  pSegment and pLinearDeviceSegment are invalidated here
00325     ClosableObjectDestructor::operator()(pSegment);
00326     pCache->unregisterDevice(deviceId);
00327     pSegmentFactory->deallocateTempDeviceId(deviceId);
00328 }
00329 
00330 SnapshotRandomAllocationSegment *SegmentFactory::getSnapshotSegment(
00331     SharedSegment pSegment)
00332 {
00333     SnapshotRandomAllocationSegment *pSnapshotSegment =
00334         SegmentFactory::dynamicCast<SnapshotRandomAllocationSegment *>(
00335             pSegment);
00336     if (pSnapshotSegment == NULL) {
00337         DynamicDelegatingSegment *pDynamicSegment =
00338             SegmentFactory::dynamicCast<DynamicDelegatingSegment *>(
00339                 pSegment);
00340         if (pDynamicSegment != NULL) {
00341             pSnapshotSegment =
00342                 SegmentFactory::dynamicCast<SnapshotRandomAllocationSegment *>(
00343                     pDynamicSegment->getDelegateSegment());
00344         }
00345     }
00346     return pSnapshotSegment;
00347 }
00348 
00349 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/segment/SegmentFactory.cpp#19 $");
00350 
00351 // End SegmentFactory.cpp

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