00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
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     
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 ¶ms)
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     
00098     
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     
00120     
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         
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 
00260 SharedSegment SegmentFactory::newTempDeviceSegment(
00261     SharedCache pCache,
00262     DeviceMode deviceMode,
00263     std::string deviceFileName)
00264 {
00265     
00266     DeviceId deviceId = allocateTempDeviceId();
00267     if (deviceMode.create) {
00268         FileSystem::remove(deviceFileName.c_str());
00269     }
00270     
00271     
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     
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     
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