00001 /* 00002 // $Id: //open/dev/fennel/test/RandomAllocationSegmentTest.cpp#5 $ 00003 // Fennel is a library of data storage and processing components. 00004 // Copyright (C) 2008-2009 The Eigenbase Project 00005 // Copyright (C) 2008-2009 SQLstream, Inc. 00006 // Copyright (C) 2008-2009 LucidEra, Inc. 00007 // 00008 // This program is free software; you can redistribute it and/or modify it 00009 // under the terms of the GNU General Public License as published by the Free 00010 // Software Foundation; either version 2 of the License, or (at your option) 00011 // any later version approved by The Eigenbase Project. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with this program; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 #include "fennel/common/CommonPreamble.h" 00024 #include "fennel/test/SegmentTestBase.h" 00025 #include "fennel/segment/SegPageLock.h" 00026 #include "fennel/cache/Cache.h" 00027 #include "fennel/cache/CacheStats.h" 00028 00029 #include <boost/test/test_tools.hpp> 00030 00031 using namespace fennel; 00032 00033 class RandomAllocationSegmentTest : virtual public SegmentTestBase 00034 { 00035 // TODO jvs 13-Jan-2008: Need many more tests here... 00036 00037 void testAllocateAndDeallocate(); 00038 00039 public: 00040 explicit RandomAllocationSegmentTest() 00041 { 00042 FENNEL_UNIT_TEST_CASE( 00043 RandomAllocationSegmentTest, testAllocateAndDeallocate); 00044 } 00045 }; 00046 00047 void RandomAllocationSegmentTest::testAllocateAndDeallocate() 00048 { 00049 openStorage(DeviceMode::createNew); 00050 openRandomSegment(); 00051 00052 // Allocate 100 pages 00053 std::vector<PageId> pageList; 00054 uint n = 100; 00055 SegmentAccessor segAccessor(pRandomSegment, pCache); 00056 SegPageLock segPageLock(segAccessor); 00057 for (uint i = 0; i < n; ++i) { 00058 PageId pageId = segPageLock.allocatePage(); 00059 BOOST_CHECK(pRandomSegment->isPageIdAllocated(pageId)); 00060 pageList.push_back(pageId); 00061 00062 // Perform a dummy write 00063 segPageLock.getPage().getWritableData(); 00064 segPageLock.unlock(); 00065 } 00066 00067 // Verify that all are still allocated 00068 for (uint i = 0; i < n; ++i) { 00069 BOOST_CHECK(pRandomSegment->isPageIdAllocated(pageList[i])); 00070 } 00071 00072 // Verify that the page count matches what's been allocated 00073 uint nAllocated = pRandomSegment->getAllocatedSizeInPages(); 00074 BOOST_REQUIRE(nAllocated == n); 00075 00076 // Verify that the high water page occupied count exceeds the allocated 00077 // count 00078 uint highWaterMarkBefore = pRandomSegment->getNumPagesOccupiedHighWater(); 00079 BOOST_REQUIRE(highWaterMarkBefore > n); 00080 00081 // Save cache stats before deallocation 00082 CacheStats statsBefore; 00083 pCache->collectStats(statsBefore); 00084 00085 // Deallocate all 00086 for (uint i = 0; i < n; ++i) { 00087 PageId pageId = pageList[i]; 00088 pRandomSegment->deallocatePageRange(pageId, pageId); 00089 BOOST_CHECK(!pRandomSegment->isPageIdAllocated(pageId)); 00090 } 00091 00092 // Make sure the high water mark stays the same even after deallocation 00093 uint highWaterMarkAfter = pRandomSegment->getNumPagesOccupiedHighWater(); 00094 BOOST_REQUIRE(highWaterMarkAfter == highWaterMarkBefore); 00095 00096 // Get cache stats after deallocation and compare 00097 CacheStats statsAfter; 00098 pCache->collectStats(statsAfter); 00099 00100 // Count of unused pages should go up since deallocation results 00101 // in discard. 00102 BOOST_CHECK(statsAfter.nMemPagesUnused > statsBefore.nMemPagesUnused); 00103 00104 // Verify that all are still deallocated 00105 for (uint i = 0; i < n; ++i) { 00106 BOOST_CHECK(!pRandomSegment->isPageIdAllocated(pageList[i])); 00107 } 00108 00109 // Allocate the pages again, and recheck the highwater mark to make 00110 // sure it's still the same 00111 for (uint i = 0; i < n; ++i) { 00112 PageId pageId = segPageLock.allocatePage(); 00113 } 00114 highWaterMarkAfter = pRandomSegment->getNumPagesOccupiedHighWater(); 00115 BOOST_REQUIRE(highWaterMarkAfter == highWaterMarkBefore); 00116 } 00117 00118 FENNEL_UNIT_TEST_SUITE(RandomAllocationSegmentTest); 00119 00120 // End RandomAllocationSegmentTest.cpp