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/test/SnapshotSegmentTestBase.h"
00026 #include "fennel/segment/VersionedRandomAllocationSegment.h"
00027 #include "fennel/cache/CacheStats.h"
00028
00029 #include <boost/test/test_tools.hpp>
00030
00031 using namespace fennel;
00032
00033 class SnapshotSegmentTest : virtual public SnapshotSegmentTestBase
00034 {
00035 public:
00036 explicit SnapshotSegmentTest()
00037 {
00038 FENNEL_UNIT_TEST_CASE(SegmentTestBase, testSingleThread);
00039 FENNEL_UNIT_TEST_CASE(PagingTestBase, testMultipleThreads);
00040 FENNEL_UNIT_TEST_CASE(SnapshotSegmentTest, testSnapshotReads);
00041 FENNEL_UNIT_TEST_CASE(SnapshotSegmentTest, testRollback);
00042 FENNEL_UNIT_TEST_CASE(SnapshotSegmentTest, testUncommittedReads);
00043 FENNEL_UNIT_TEST_CASE(SnapshotSegmentTest, testDeallocateOld);
00044 }
00045
00046 void testSnapshotReads()
00047 {
00048
00049
00050 currCsn = TxnId(0);
00051 openStorage(DeviceMode::createNew);
00052 testAllocateAll();
00053 closeStorage();
00054
00055
00056 updatedCsns.push_back(TxnId(5));
00057 currCsn = TxnId(5);
00058 openStorage(DeviceMode::load);
00059 testSkipWrite(5);
00060 closeStorage();
00061
00062
00063 updatedCsns.push_back(TxnId(7));
00064 currCsn = TxnId(7);
00065 openStorage(DeviceMode::load);
00066 testSkipWrite(7);
00067 closeStorage();
00068
00069
00070 for (uint i = 0; i < 10; i++) {
00071 currCsn = TxnId(i);
00072 openStorage(DeviceMode::load);
00073 testSequentialRead();
00074 closeStorage();
00075 }
00076 }
00077
00078 void testRollback()
00079 {
00080
00081
00082 currCsn = TxnId(0);
00083 openStorage(DeviceMode::createNew);
00084 testAllocateAll();
00085 closeStorage();
00086
00087
00088
00089 currCsn = TxnId(1);
00090 openStorage(DeviceMode::load);
00091 testSkipWrite(5);
00092
00093 assert(
00094 pVersionedRandomSegment->getAllocatedSizeInPages() ==
00095 nDiskPages + nDiskPages / 5 + ((nDiskPages % 5) ? 1 : 0));
00096 commit = false;
00097 closeStorage();
00098 commit = true;
00099
00100
00101
00102 currCsn = TxnId(2);
00103 openStorage(DeviceMode::load);
00104 testSequentialRead();
00105 closeStorage();
00106 }
00107
00108 void testUncommittedReads()
00109 {
00110
00111
00112 currCsn = TxnId(0);
00113 openStorage(DeviceMode::createNew);
00114 testAllocateAll();
00115 closeStorage();
00116
00117
00118
00119 currCsn = TxnId(5);
00120 openStorage(DeviceMode::load);
00121 testSkipWrite(5);
00122
00123
00124
00125 closeLinearSegment();
00126 pSnapshotRandomSegment2 =
00127 pSegmentFactory->newSnapshotRandomAllocationSegment(
00128 pVersionedRandomSegment,
00129 pVersionedRandomSegment,
00130 TxnId(6));
00131 setForceCacheUnmap(pSnapshotRandomSegment2);
00132 SharedSegment pLinearViewSegment =
00133 pSegmentFactory->newLinearViewSegment(
00134 pSnapshotRandomSegment2,
00135 firstPageId);
00136 pLinearSegment = pLinearViewSegment;
00137
00138
00139
00140 testSequentialRead();
00141 pLinearViewSegment.reset();
00142
00143
00144
00145 pSnapshotRandomSegment2.reset();
00146 closeLinearSegment();
00147 pSnapshotRandomSegment2 =
00148 pSegmentFactory->newSnapshotRandomAllocationSegment(
00149 pVersionedRandomSegment,
00150 pVersionedRandomSegment,
00151 TxnId(5),
00152 true);
00153 setForceCacheUnmap(pSnapshotRandomSegment2);
00154 pLinearViewSegment =
00155 pSegmentFactory->newLinearViewSegment(
00156 pSnapshotRandomSegment2,
00157 firstPageId);
00158 pLinearSegment = pLinearViewSegment;
00159 testSequentialRead();
00160 pLinearViewSegment.reset();
00161
00162
00163 closeStorage();
00164
00165
00166 updatedCsns.push_back(TxnId(5));
00167 currCsn = TxnId(6);
00168 openStorage(DeviceMode::load);
00169 testSequentialRead();
00170 closeStorage();
00171 }
00172
00173 void testDeallocateOld()
00174 {
00175
00176
00177 currCsn = TxnId(0);
00178 openStorage(DeviceMode::createNew);
00179 testAllocateAll();
00180 closeStorage();
00181
00182
00183 updatedCsns.push_back(TxnId(3));
00184 currCsn = TxnId(3);
00185 openStorage(DeviceMode::load);
00186 testSkipWrite(3);
00187 closeStorage();
00188
00189
00190 updatedCsns.push_back(TxnId(5));
00191 currCsn = TxnId(5);
00192 openStorage(DeviceMode::load);
00193 testSkipWrite(5);
00194 closeStorage();
00195
00196
00197 updatedCsns.push_back(TxnId(7));
00198 currCsn = TxnId(7);
00199 openStorage(DeviceMode::load);
00200 testSkipWrite(7);
00201 closeStorage();
00202
00203 uint totalPages =
00204 nDiskPages +
00205 nDiskPages / 3 + ((nDiskPages % 3) ? 1 : 0) +
00206 nDiskPages / 5 + ((nDiskPages % 5) ? 1 : 0) +
00207 nDiskPages / 7 + ((nDiskPages % 7) ? 1 : 0);
00208
00209
00210
00211 deallocateOldPages(TxnId(3), totalPages, totalPages, 3, 8);
00212
00213
00214
00215 deallocateOldPages(TxnId(4), totalPages, totalPages, 4, 8);
00216
00217
00218
00219
00220 uint nPages =
00221 totalPages - (nDiskPages/(3*5) + ((nDiskPages % (3*5)) ? 1 : 0));
00222 deallocateOldPages(TxnId(6), totalPages, nPages, 6, 8);
00223
00224
00225
00226
00227 totalPages = nPages;
00228 nPages =
00229 totalPages -
00230 (nDiskPages/(5*7) + ((nDiskPages % (5*7)) ? 1 : 0)) -
00231 (nDiskPages/(3*7) + ((nDiskPages % (3*7)) ? 1 : 0)) +
00232 (nDiskPages/(3*5*7) + ((nDiskPages % (3*5*7)) ? 1 : 0));
00233 deallocateOldPages(TxnId(8), totalPages, nPages, 8, 8);
00234
00235
00236
00237 currCsn = TxnId(9);
00238 openStorage(DeviceMode::load);
00239
00240
00241 testSequentialRead();
00242
00243
00244 CacheStats statsBefore;
00245 pCache->collectStats(statsBefore);
00246
00247 for (int i = opaqueToInt(firstPageId);
00248 i < 100 + opaqueToInt(firstPageId); i++)
00249 {
00250 pSnapshotRandomSegment->deallocatePageRange(PageId(i), PageId(i));
00251 }
00252
00253
00254 CacheStats statsAfter;
00255 pCache->collectStats(statsAfter);
00256
00257
00258
00259 BOOST_CHECK(statsAfter.nMemPagesUnused <= statsBefore.nMemPagesUnused);
00260
00261 closeStorage();
00262
00263
00264
00265 deallocateOldPages(TxnId(0), nPages, nPages, 8, 8);
00266
00267
00268
00269
00270
00271 int nPagesFreed =
00272 100 + 100/3 + 100/5 + 100/7 - 100/(3*5) - 100/(3*7) - 100/(5*7)
00273 - 100/(3*5*7);
00274 deallocateOldPages(TxnId(10), nPages, nPages - nPagesFreed, 1, 0);
00275 }
00276
00277 void deallocateOldPages(
00278 TxnId oldestActiveTxnId,
00279 uint numPagesBefore,
00280 uint numPagesAfter,
00281 uint readStart,
00282 uint readEnd)
00283 {
00284 currCsn = TxnId(10);
00285 openStorage(DeviceMode::load);
00286 VersionedRandomAllocationSegment *pVRSegment =
00287 SegmentFactory::dynamicCast<VersionedRandomAllocationSegment *>(
00288 pVersionedRandomSegment);
00289 uint nPages = pVRSegment->getAllocatedSizeInPages();
00290 assert(nPages == numPagesBefore);
00291 uint iSegAlloc = 0;
00292 ExtentNum extentNum = 0;
00293 uint numPages = 100;
00294 PageSet oldPageSet;
00295 bool morePages = true;
00296 do {
00297 morePages =
00298 pVRSegment->getOldPageIds(
00299 iSegAlloc,
00300 extentNum,
00301 oldestActiveTxnId,
00302 numPages,
00303 oldPageSet);
00304 pVRSegment->deallocateOldPages(oldPageSet, oldestActiveTxnId);
00305 oldPageSet.clear();
00306 } while (morePages);
00307 nPages = pVRSegment->getAllocatedSizeInPages();
00308 assert(nPages == numPagesAfter);
00309 closeStorage();
00310
00311
00312 for (uint i = readStart; i <= readEnd; i++) {
00313 currCsn = TxnId(i);
00314 openStorage(DeviceMode::load);
00315 testSequentialRead();
00316 closeStorage();
00317 }
00318 }
00319 };
00320
00321 FENNEL_UNIT_TEST_SUITE(SnapshotSegmentTest);
00322
00323