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