From: <mar...@us...> - 2010-12-20 08:57:52
|
Revision: 4023 http://bigdata.svn.sourceforge.net/bigdata/?rev=4023&view=rev Author: martyncutcher Date: 2010-12-20 08:57:44 +0000 (Mon, 20 Dec 2010) Log Message: ----------- fix to AllocBlock releaseSession for higher bit allocations and addition test_stressSessionProtection Modified Paths: -------------- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/AllocBlock.java branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/AllocBlock.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/AllocBlock.java 2010-12-19 23:36:02 UTC (rev 4022) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/java/com/bigdata/rwstore/AllocBlock.java 2010-12-20 08:57:44 UTC (rev 4023) @@ -321,11 +321,12 @@ m_transients[i] = m_live[i] | m_commit[i]; chkbits &= ~m_transients[i]; + final int startBit = i * 32; if (chkbits != 0) { // there are writes to clear for (int b = 0; b < 32; b++) { if ((chkbits & (1 << b)) != 0) { - long clr = RWStore.convertAddr(m_addr) + ((long) m_allocator.m_size * b); + long clr = RWStore.convertAddr(m_addr) + ((long) m_allocator.m_size * (startBit + b)); if (log.isTraceEnabled()) log.trace("releasing address: " + clr); Modified: branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java =================================================================== --- branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2010-12-19 23:36:02 UTC (rev 4022) +++ branches/JOURNAL_HA_BRANCH/bigdata/src/test/com/bigdata/rwstore/TestRWJournal.java 2010-12-20 08:57:44 UTC (rev 4023) @@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + */ /* * Created on Oct 14, 2006 */ @@ -37,6 +37,10 @@ import junit.extensions.proxy.ProxyTestSuite; import junit.framework.Test; +import com.bigdata.btree.IIndex; +import com.bigdata.btree.ITuple; +import com.bigdata.btree.ITupleIterator; +import com.bigdata.btree.IndexMetadata; import com.bigdata.config.LongValidator; import com.bigdata.journal.AbstractInterruptsTestCase; import com.bigdata.journal.AbstractJournalTestCase; @@ -44,7 +48,10 @@ import com.bigdata.journal.AbstractMROWTestCase; import com.bigdata.journal.AbstractRestartSafeTestCase; import com.bigdata.journal.BufferMode; +import com.bigdata.journal.CommitRecordIndex; +import com.bigdata.journal.CommitRecordSerializer; import com.bigdata.journal.DiskOnlyStrategy; +import com.bigdata.journal.ICommitRecord; import com.bigdata.journal.Journal; import com.bigdata.journal.RWStrategy; import com.bigdata.journal.TestJournalBasics; @@ -56,617 +63,623 @@ /** * Test suite for {@link BufferMode#DiskRW} journals. * - * TODO: must modify RWStore to use DirectBufferPool to allocate and release buffers, - * Once done then ensure the write cache is enabled when running test suite + * TODO: must modify RWStore to use DirectBufferPool to allocate and release + * buffers, Once done then ensure the write cache is enabled when running test + * suite * * @author <a href="mailto:tho...@us...">Bryan Thompson</a> * @version $Id$ */ public class TestRWJournal extends AbstractJournalTestCase { - public TestRWJournal() { - super(); - } + public TestRWJournal() { + super(); + } - public TestRWJournal(String name) { - super(name); - } + public TestRWJournal(String name) { + super(name); + } - public static Test suite() { + public static Test suite() { - final TestRWJournal delegate = new TestRWJournal(); // !!!! THIS CLASS !!!! + final TestRWJournal delegate = new TestRWJournal(); // !!!! THIS CLASS + // !!!! - /* - * Use a proxy test suite and specify the delegate. - */ + /* + * Use a proxy test suite and specify the delegate. + */ - final ProxyTestSuite suite = new ProxyTestSuite(delegate, - "Disk RW Journal Test Suite"); + final ProxyTestSuite suite = new ProxyTestSuite(delegate, "Disk RW Journal Test Suite"); - /* - * List any non-proxied tests (typically bootstrapping tests). - */ - - // tests defined by this class. - suite.addTestSuite(TestRWJournal.class); + /* + * List any non-proxied tests (typically bootstrapping tests). + */ - // test suite for the IRawStore api. - suite.addTestSuite(TestRawStore.class); + // tests defined by this class. + suite.addTestSuite(TestRWJournal.class); - // test suite for handling asynchronous close of the file channel. - suite.addTestSuite(TestInterrupts.class); + // test suite for the IRawStore api. + suite.addTestSuite(TestRawStore.class); - // test suite for MROW correctness. - suite.addTestSuite(TestMROW.class); + // test suite for handling asynchronous close of the file channel. + suite.addTestSuite(TestInterrupts.class); - // test suite for MRMW correctness. - suite.addTestSuite(TestMRMW.class); + // test suite for MROW correctness. + suite.addTestSuite(TestMROW.class); - /* - * Pickup the basic journal test suite. This is a proxied test suite, so - * all the tests will run with the configuration specified in this test - * class and its optional .properties file. - */ - suite.addTest(TestJournalBasics.suite()); - - return suite; + // test suite for MRMW correctness. + suite.addTestSuite(TestMRMW.class); - } + /* + * Pickup the basic journal test suite. This is a proxied test suite, so + * all the tests will run with the configuration specified in this test + * class and its optional .properties file. + */ + suite.addTest(TestJournalBasics.suite()); - public Properties getProperties() { + return suite; - final Properties properties = super.getProperties(); + } - properties.setProperty(Options.BUFFER_MODE, BufferMode.DiskRW.toString()); - // properties.setProperty(Options.BUFFER_MODE, BufferMode.TemporaryRW.toString()); + public Properties getProperties() { - // properties.setProperty(Options.CREATE_TEMP_FILE, "true"); - - // properties.setProperty(Options.FILE, "/Volumes/SSDData/TestRW/tmp.rw"); + final Properties properties = super.getProperties(); - properties.setProperty(Options.DELETE_ON_EXIT, "true"); + properties.setProperty(Options.BUFFER_MODE, BufferMode.DiskRW.toString()); + // properties.setProperty(Options.BUFFER_MODE, + // BufferMode.TemporaryRW.toString()); - properties.setProperty(Options.WRITE_CACHE_ENABLED, "" - + writeCacheEnabled); + // properties.setProperty(Options.CREATE_TEMP_FILE, "true"); - // number of bits in FixedAllocators - properties.setProperty(com.bigdata.rwstore.RWStore.Options.DEFAULT_FREE_BITS_THRESHOLD, "1000"); - - // Size of META_BITS_BLOCKS - properties.setProperty(com.bigdata.rwstore.RWStore.Options.DEFAULT_META_BITS_SIZE, "9"); + // properties.setProperty(Options.FILE, + // "/Volumes/SSDData/TestRW/tmp.rw"); - // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16,32"); // 2K max - properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16"); // 1K + properties.setProperty(Options.DELETE_ON_EXIT, "true"); - // ensure history retention to force deferredFrees - // properties.setProperty(AbstractTransactionService.Options.MIN_RELEASE_AGE, "1"); // Non-zero + properties.setProperty(Options.WRITE_CACHE_ENABLED, "" + writeCacheEnabled); - return properties; + // number of bits in FixedAllocators + properties.setProperty(com.bigdata.rwstore.RWStore.Options.DEFAULT_FREE_BITS_THRESHOLD, "1000"); - } - - /** - * Verify normal operation and basic assumptions when creating a new journal - * using {@link BufferMode#DiskRW}. - * - * @throws IOException - */ - public void test_create_disk01() throws IOException { + // Size of META_BITS_BLOCKS + properties.setProperty(com.bigdata.rwstore.RWStore.Options.DEFAULT_META_BITS_SIZE, "9"); - File file = null; + // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, + // "1,2,3,5,8,12,16,32"); // 2K max + properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16"); // 1K - final Properties properties = getProperties(); + // ensure history retention to force deferredFrees + // properties.setProperty(AbstractTransactionService.Options.MIN_RELEASE_AGE, + // "1"); // Non-zero - final Journal journal = new Journal(properties); + return properties; - try { + } - final RWStrategy bufferStrategy = (RWStrategy) journal - .getBufferStrategy(); + /** + * Verify normal operation and basic assumptions when creating a new journal + * using {@link BufferMode#DiskRW}. + * + * @throws IOException + */ + public void test_create_disk01() throws IOException { - assertTrue("isStable", bufferStrategy.isStable()); - assertFalse("isFullyBuffered", bufferStrategy.isFullyBuffered()); - // assertEquals(Options.FILE, properties.getProperty(Options.FILE), - // bufferStrategy.file.toString()); - assertEquals(Options.INITIAL_EXTENT, Long - .parseLong(Options.DEFAULT_INITIAL_EXTENT), bufferStrategy - .getInitialExtent()); - assertEquals(Options.MAXIMUM_EXTENT, - 0L/* soft limit for disk mode */, bufferStrategy - .getMaximumExtent()); -// assertNotNull("raf", bufferStrategy.getRandomAccessFile()); - assertEquals(Options.BUFFER_MODE, BufferMode.DiskRW, bufferStrategy - .getBufferMode()); + File file = null; - file = journal.getFile(); - - } finally { + final Properties properties = getProperties(); - journal.destroy(); + final Journal journal = new Journal(properties); - } + try { - if(file != null && file.exists()) - fail("Did not delete the backing file: "+file); - - } - - /** - * Unit test verifies that {@link Options#CREATE} may be used to initialize - * a journal on a newly created empty file. - * - * @throws IOException - */ - public void test_create_emptyFile() throws IOException { - - final File file = File.createTempFile(getName(), Options.JNL); + final RWStrategy bufferStrategy = (RWStrategy) journal.getBufferStrategy(); - final Properties properties = new Properties(); + assertTrue("isStable", bufferStrategy.isStable()); + assertFalse("isFullyBuffered", bufferStrategy.isFullyBuffered()); + // assertEquals(Options.FILE, properties.getProperty(Options.FILE), + // bufferStrategy.file.toString()); + assertEquals(Options.INITIAL_EXTENT, Long.parseLong(Options.DEFAULT_INITIAL_EXTENT), bufferStrategy + .getInitialExtent()); + assertEquals(Options.MAXIMUM_EXTENT, 0L/* soft limit for disk mode */, bufferStrategy.getMaximumExtent()); + // assertNotNull("raf", bufferStrategy.getRandomAccessFile()); + assertEquals(Options.BUFFER_MODE, BufferMode.DiskRW, bufferStrategy.getBufferMode()); - properties.setProperty(Options.BUFFER_MODE, BufferMode.DiskRW.toString()); + file = journal.getFile(); - properties.setProperty(Options.FILE, file.toString()); + } finally { - properties.setProperty(Options.WRITE_CACHE_ENABLED, "" - + writeCacheEnabled); + journal.destroy(); - final Journal journal = new Journal(properties); + } - try { + if (file != null && file.exists()) + fail("Did not delete the backing file: " + file); - assertEquals(file, journal.getFile()); + } - } finally { + /** + * Unit test verifies that {@link Options#CREATE} may be used to initialize + * a journal on a newly created empty file. + * + * @throws IOException + */ + public void test_create_emptyFile() throws IOException { - journal.destroy(); + final File file = File.createTempFile(getName(), Options.JNL); - } + final Properties properties = new Properties(); - } + properties.setProperty(Options.BUFFER_MODE, BufferMode.DiskRW.toString()); - /** - * Test suite integration for {@link AbstractRestartSafeTestCase}. - * - * @todo there are several unit tests in this class that deal with - * {@link DiskOnlyStrategy#allocate(int)} and - * {@link DiskOnlyStrategy#update(long, int, ByteBuffer)}. If those - * methods are added to the {@link IRawStore} API then move these unit - * tests into {@link AbstractRawStoreTestCase}. - * - * @author <a href="mailto:tho...@us...">Bryan Thompson</a> - * @version $Id$ - */ - public static class TestRawStore extends AbstractRestartSafeTestCase { - - public TestRawStore() { - super(); - } + properties.setProperty(Options.FILE, file.toString()); - public TestRawStore(String name) { - super(name); - } + properties.setProperty(Options.WRITE_CACHE_ENABLED, "" + writeCacheEnabled); - protected BufferMode getBufferMode() { - - return BufferMode.DiskRW; - // return BufferMode.TemporaryRW; - - } + final Journal journal = new Journal(properties); - public Properties getProperties() { - - System.out.println("TestRWJournal:getProperties"); + try { - final Properties properties = super.getProperties(); + assertEquals(file, journal.getFile()); - properties.setProperty(Options.BUFFER_MODE, BufferMode.DiskRW.toString()); - // properties.setProperty(Options.BUFFER_MODE, BufferMode.TemporaryRW.toString()); + } finally { - properties.setProperty(Options.CREATE_TEMP_FILE, "true"); - - // properties.setProperty(Options.FILE, "/Volumes/SSDData/TestRW/tmp.rw"); -// properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16,32,48,64,128,192,320,512,832,1344,2176,3520"); - // properties.setProperty(Options.RW_ALLOCATIONS, "1,2,3,5,8,12,16,32,48,64"); + journal.destroy(); - properties.setProperty(Options.DELETE_ON_EXIT, "true"); + } - properties.setProperty(Options.WRITE_CACHE_ENABLED, "" - + writeCacheEnabled); + } - // number of bits in FixedAllocators - properties.setProperty(RWStore.Options.FREE_BITS_THRESHOLD, "50"); - - // Size of META_BITS_BLOCKS - properties.setProperty(RWStore.Options.META_BITS_SIZE, "9"); + /** + * Test suite integration for {@link AbstractRestartSafeTestCase}. + * + * @todo there are several unit tests in this class that deal with + * {@link DiskOnlyStrategy#allocate(int)} and + * {@link DiskOnlyStrategy#update(long, int, ByteBuffer)}. If those + * methods are added to the {@link IRawStore} API then move these unit + * tests into {@link AbstractRawStoreTestCase}. + * + * @author <a href="mailto:tho...@us...">Bryan + * Thompson</a> + * @version $Id: TestRWJournal.java 4010 2010-12-16 12:44:43Z martyncutcher + * $ + */ + public static class TestRawStore extends AbstractRestartSafeTestCase { - // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16,32,48,64,128"); // 8K - max blob = 2K * 8K = 16M - // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16,32,48,64,128"); // 2K max - properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16"); // 2K max + public TestRawStore() { + super(); + } - // ensure history retention to force deferredFrees - // properties.setProperty(AbstractTransactionService.Options.MIN_RELEASE_AGE, "1"); // Non-zero + public TestRawStore(String name) { + super(name); + } - return properties; + protected BufferMode getBufferMode() { - } - - protected IRawStore getStore() { - - return new Journal(getProperties()); - - } - -// /** -// * Test that allocate() pre-extends the store when a record is allocated -// * which would overflow the current user extent. -// */ -// public void test_allocPreExtendsStore() { -// -// final Journal store = (Journal) getStore(); -// -// try { -// -// final DiskOnlyStrategy bufferStrategy = (DiskOnlyStrategy) store -// .getBufferStrategy(); -// -// final long nextOffset = store.getRootBlockView() -// .getNextOffset(); -// -// final long length = store.size(); -// -// final long headerSize = FileMetadata.headerSize0; -// -// // #of bytes remaining in the user extent before overflow. -// final long nfree = length - (headerSize + nextOffset); -// -// if (nfree >= Integer.MAX_VALUE) { -// -// /* -// * The test is trying to allocate a single record that will -// * force the store to be extended. This will not work if the -// * store file already has a huge user extent with nothing -// * allocated on it. -// */ -// -// fail("Can't allocate a record with: " + nfree + " bytes"); -// -// } -// -// final int nbytes = (int) nfree; -// -// final long addr = bufferStrategy.allocate(nbytes); -// -// assertNotSame(0L, addr); -// -// assertEquals(nbytes, store.getByteCount(addr)); -// -// // store file was extended. -// assertTrue(store.size() > length); -// -// } finally { -// -// store.destroy(); -// -// } -// -// } + return BufferMode.DiskRW; + // return BufferMode.TemporaryRW; - /** - * Test allocate()+read() where the record was never written (the data - * are undefined unless written so there is nothing really to test here - * except for exceptions which might be through for this condition). - */ - public void test_allocate_then_read() {} + } - /** - * Reallocates the same object several times, then commits and tests read back. - * - * - */ - public void test_reallocate() { - final Journal store = (Journal) getStore(); + public Properties getProperties() { - try { + System.out.println("TestRWJournal:getProperties"); - byte[] buf = new byte[1024]; // 2Mb buffer of random data - r.nextBytes(buf); - - ByteBuffer bb = ByteBuffer.wrap(buf); + final Properties properties = super.getProperties(); - RWStrategy bs = (RWStrategy) store - .getBufferStrategy(); + properties.setProperty(Options.BUFFER_MODE, BufferMode.DiskRW.toString()); + // properties.setProperty(Options.BUFFER_MODE, + // BufferMode.TemporaryRW.toString()); - RWStore rw = bs.getRWStore(); - - long faddr1 = bs.write(bb); - bb.position(0); - //bs.delete(faddr); - - long faddr2 = bs.write(bb); - bb.position(0); - - store.commit(); - - rw.reset(); - - ByteBuffer inbb1 = bs.read(faddr1); - ByteBuffer inbb2 = bs.read(faddr2); - - assertEquals(bb, inbb1); - assertEquals(bb, inbb2); - - } finally { - store.destroy(); - } - - } - - /** - * Test write of a record and then update of a slice of that record. - * <p> - * Note: Since the record was written but not flushed it will be found - * in the write cache by update(). - */ - public void test_write_plus_update() {} - - /** - * Ensures the allocation of unique addresses by mapping allocated address with uniqueness - * assertion against physical address. - */ - public void test_addressing() { - - final Journal store = (Journal) getStore(); + properties.setProperty(Options.CREATE_TEMP_FILE, "true"); - try { + // properties.setProperty(Options.FILE, + // "/Volumes/SSDData/TestRW/tmp.rw"); + // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, + // "1,2,3,5,8,12,16,32,48,64,128,192,320,512,832,1344,2176,3520"); + // properties.setProperty(Options.RW_ALLOCATIONS, + // "1,2,3,5,8,12,16,32,48,64"); - RWStrategy bufferStrategy = (RWStrategy) store - .getBufferStrategy(); + properties.setProperty(Options.DELETE_ON_EXIT, "true"); - RWStore rw = bufferStrategy.getRWStore(); - ArrayList<Integer> sizes = new ArrayList<Integer>(); - TreeMap<Long, Integer> paddrs = new TreeMap<Long, Integer>(); - for (int i = 0; i < 100000; i++) { - int s = r.nextInt(250)+1; - sizes.add(s); - int a = rw.alloc(s, null); - long pa = rw.physicalAddress(a); - assertTrue(paddrs.get(pa) == null); - paddrs.put(pa, a); - } - - for (int i = 0; i < 50; i++) { - int s = r.nextInt(500)+1; - sizes.add(s); - int a = rw.alloc(s, null); - long pa = rw.physicalAddress(a); - paddrs.put(pa, a); - } - - } finally { + properties.setProperty(Options.WRITE_CACHE_ENABLED, "" + writeCacheEnabled); - store.destroy(); - - } + // number of bits in FixedAllocators + properties.setProperty(RWStore.Options.FREE_BITS_THRESHOLD, "50"); - - } - - /** - * Basic allocation test to ensure the FixedAllocators are operating efficiently. - * - * A 90 byte allocation is expected to fit in a 128byte block. If we only allocate - * this fixed block size, then we would expect the physical address to increase by 128 bytes - * for each allocation. - */ - public void test_allocations() { - - Journal store = (Journal) getStore(); + // Size of META_BITS_BLOCKS + properties.setProperty(RWStore.Options.META_BITS_SIZE, "9"); - try { + // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, + // "1,2,3,5,8,12,16,32,48,64,128"); // 8K - max blob = 2K * 8K = 16M + // properties.setProperty(RWStore.Options.ALLOCATION_SIZES, + // "1,2,3,5,8,12,16,32,48,64,128"); // 2K max + properties.setProperty(RWStore.Options.ALLOCATION_SIZES, "1,2,3,5,8,12,16"); // 2K + // max - RWStrategy bufferStrategy = (RWStrategy) store - .getBufferStrategy(); + // ensure history retention to force deferredFrees + // properties.setProperty(AbstractTransactionService.Options.MIN_RELEASE_AGE, + // "1"); // Non-zero - RWStore rw = bufferStrategy.getRWStore(); - long numAllocs = rw.getTotalAllocations(); - long startAllocations = rw.getTotalAllocationsSize(); - long faddr = allocBatch(rw, 1000, 275, 320); - faddr = allocBatch(rw, 10000, 90, 128); - faddr = allocBatch(rw, 20000, 45, 64); - - System.out.println("Final allocation: " + faddr - + ", allocations: " + (rw.getTotalAllocations() - numAllocs) - + ", allocated bytes: " + (rw.getTotalAllocationsSize() - startAllocations)); - - store.commit(); - - // Confirm that we can re-open the journal after commit - store = (Journal) reopenStore(store); - - } finally { + return properties; - store.destroy(); - - } + } - - } - - /** - * Not so much a test as a code coverage exercise. - * - * The output from showAllocReserve confirms the relative merits of - * optimising for space vs density. The DirectFixedAllocators will - * allocate from DirectBuffers, where locality of reference is less - * important than efficient management of the memory, which is optimised - * by allocations in smaller amounts that match the demands at a finer - * granularity. - */ - public void testAllocationReserves() { - final int cReserve16K = 16 * 1024; - final int cReserve128K = 32 * 1024; - - showAllocReserve(false, 64, cReserve16K, cReserve16K); - showAllocReserve(false, 128, cReserve16K, cReserve16K); - showAllocReserve(false, 1024, cReserve16K, cReserve16K); - showAllocReserve(false, 2048, cReserve16K, cReserve16K); - showAllocReserve(false, 3072, cReserve16K, cReserve16K); - showAllocReserve(false, 4096, cReserve16K, cReserve16K); - showAllocReserve(false, 8192, cReserve16K, cReserve16K); - - showAllocReserve(true, 64, cReserve128K, cReserve16K); - showAllocReserve(true, 128, cReserve128K, cReserve16K); - showAllocReserve(true, 1024, cReserve128K, cReserve16K); - showAllocReserve(true, 2048, cReserve128K, cReserve16K); - showAllocReserve(true, 3072, cReserve128K, cReserve16K); - showAllocReserve(true, 4096, cReserve128K, cReserve16K); - showAllocReserve(true, 8192, cReserve128K, cReserve16K); - } - private void showAllocReserve(final boolean optDensity, final int slotSize, final int reserve, final int mod) { - final int ints = FixedAllocator.calcBitSize(optDensity, slotSize, reserve, mod); - // there are max 254 ints available to a FixedAllocator - final int maxuse = (254/(ints+1)) * ints; - System.out.println("Allocate " + ints + ":" + (32 * ints * slotSize) + " for " + slotSize + " in " + reserve + " using " + maxuse + " of 254 possible"); - } - - long allocBatch(RWStore rw, int bsize, int asze, int ainc) { - long curAddress = rw.physicalAddress(rw.alloc(asze, null)); - for (int i = 1; i < bsize; i++) { - int a = rw.alloc(asze, null); - long nxt = rw.physicalAddress(a); - assertTrue("Problem with index: " + i, diff(curAddress, nxt) == ainc || (nxt % 8192 == 0)); - curAddress = nxt; - } - - return curAddress; - } - - int diff(final long cur, final long nxt) { - int ret = (int) (nxt - cur); - return ret < 0 ? -ret : ret; - } + protected IRawStore getStore() { - int[] allocBatchBuffer(RWStore rw, int bsize, int base, int scope) { - int[] retaddrs = new int[bsize]; - - byte[] batchBuffer = new byte[base+scope]; - r.nextBytes(batchBuffer); - for (int i = 0; i < bsize; i++) { - int as = base + r.nextInt(scope); - retaddrs[i] = (int) rw.alloc(batchBuffer, as, null); - } - - return retaddrs; - } + return new Journal(getProperties()); - - /** - * Reallocation tests the freeing of allocated address and the re-use - * within a transaction. - * - * The repeated runs with full reopening of the store check the - * initialization of the allocators on reload. - * - * @throws IOException - */ - public void test_reallocation() throws IOException { - final Properties properties = getProperties(); - File tmpfile = File.createTempFile("TestRW", "rw"); - properties.setProperty(Options.FILE, tmpfile.getAbsolutePath()); - properties.remove(Options.CREATE_TEMP_FILE); - Journal store = new Journal(properties); + } - try { + // /** + // * Test that allocate() pre-extends the store when a record is + // allocated + // * which would overflow the current user extent. + // */ + // public void test_allocPreExtendsStore() { + // + // final Journal store = (Journal) getStore(); + // + // try { + // + // final DiskOnlyStrategy bufferStrategy = (DiskOnlyStrategy) store + // .getBufferStrategy(); + // + // final long nextOffset = store.getRootBlockView() + // .getNextOffset(); + // + // final long length = store.size(); + // + // final long headerSize = FileMetadata.headerSize0; + // + // // #of bytes remaining in the user extent before overflow. + // final long nfree = length - (headerSize + nextOffset); + // + // if (nfree >= Integer.MAX_VALUE) { + // + // /* + // * The test is trying to allocate a single record that will + // * force the store to be extended. This will not work if the + // * store file already has a huge user extent with nothing + // * allocated on it. + // */ + // + // fail("Can't allocate a record with: " + nfree + " bytes"); + // + // } + // + // final int nbytes = (int) nfree; + // + // final long addr = bufferStrategy.allocate(nbytes); + // + // assertNotSame(0L, addr); + // + // assertEquals(nbytes, store.getByteCount(addr)); + // + // // store file was extended. + // assertTrue(store.size() > length); + // + // } finally { + // + // store.destroy(); + // + // } + // + // } - RWStrategy bufferStrategy = (RWStrategy) store - .getBufferStrategy(); + /** + * Test allocate()+read() where the record was never written (the data + * are undefined unless written so there is nothing really to test here + * except for exceptions which might be through for this condition). + */ + public void test_allocate_then_read() { + } - RWStore rw = bufferStrategy.getRWStore(); - long numAllocs = rw.getTotalAllocations(); - long startAllocations = rw.getTotalAllocationsSize(); - - reallocBatch(rw, 1000, 275, 1000); - - store.commit(); - store.close(); - store = new Journal(properties); - bufferStrategy = (RWStrategy) store.getBufferStrategy(); - rw = bufferStrategy.getRWStore(); - - reallocBatch(rw, 1000, 100, 10000); - - store.commit(); - store.close(); - store = new Journal(properties); - bufferStrategy = (RWStrategy) store.getBufferStrategy(); - rw = bufferStrategy.getRWStore(); + /** + * Reallocates the same object several times, then commits and tests + * read back. + * + * + */ + public void test_reallocate() { + final Journal store = (Journal) getStore(); - reallocBatch(rw, 1000, 100, 10000); - - store.commit(); - store.close(); - store = new Journal(properties); - bufferStrategy = (RWStrategy) store.getBufferStrategy(); - rw = bufferStrategy.getRWStore(); + try { - System.out.println("Final allocations: " + (rw.getTotalAllocations() - numAllocs) - + ", allocated bytes: " + (rw.getTotalAllocationsSize() - startAllocations) - + ", file length: " + rw.getStoreFile().length()); - } finally { + byte[] buf = new byte[1024]; // 2Mb buffer of random data + r.nextBytes(buf); - store.destroy(); - - } + ByteBuffer bb = ByteBuffer.wrap(buf); - - } + RWStrategy bs = (RWStrategy) store.getBufferStrategy(); - private long reallocBatch(RWStore rw, int tsts, int sze, int grp) { - long[] addr = new long[grp]; - for (int i = 0; i < grp; i++) { - addr[i] = rw.alloc(2 + r.nextInt(sze), null); - } - for (int t = 0; t < tsts; t++) { - for (int i = 0; i < grp; i++) { - long old = addr[i]; - int asze = 2 + r.nextInt(sze); - addr[i] = rw.alloc(asze, null); - - if (i % 2 == 0) - rw.free(old, 1); // dunno what the real size is - } - } - - return 0L; + RWStore rw = bs.getRWStore(); + + long faddr1 = bs.write(bb); + bb.position(0); + // bs.delete(faddr); + + long faddr2 = bs.write(bb); + bb.position(0); + + store.commit(); + + rw.reset(); + + ByteBuffer inbb1 = bs.read(faddr1); + ByteBuffer inbb2 = bs.read(faddr2); + + assertEquals(bb, inbb1); + assertEquals(bb, inbb2); + + } finally { + store.destroy(); + } + } - - public void test_reallocationWithReadAndReopen() { - - Journal store = (Journal) getStore(); - try { + /** + * Test write of a record and then update of a slice of that record. + * <p> + * Note: Since the record was written but not flushed it will be found + * in the write cache by update(). + */ + public void test_write_plus_update() { + } + /** + * Ensures the allocation of unique addresses by mapping allocated + * address with uniqueness assertion against physical address. + */ + public void test_addressing() { + + final Journal store = (Journal) getStore(); + + try { + RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); RWStore rw = bufferStrategy.getRWStore(); - + ArrayList<Integer> sizes = new ArrayList<Integer>(); + TreeMap<Long, Integer> paddrs = new TreeMap<Long, Integer>(); + for (int i = 0; i < 100000; i++) { + int s = r.nextInt(250) + 1; + sizes.add(s); + int a = rw.alloc(s, null); + long pa = rw.physicalAddress(a); + assertTrue(paddrs.get(pa) == null); + paddrs.put(pa, a); + } + + for (int i = 0; i < 50; i++) { + int s = r.nextInt(500) + 1; + sizes.add(s); + int a = rw.alloc(s, null); + long pa = rw.physicalAddress(a); + paddrs.put(pa, a); + } + + } finally { + + store.destroy(); + + } + + } + + /** + * Basic allocation test to ensure the FixedAllocators are operating + * efficiently. + * + * A 90 byte allocation is expected to fit in a 128byte block. If we + * only allocate this fixed block size, then we would expect the + * physical address to increase by 128 bytes for each allocation. + */ + public void test_allocations() { + + Journal store = (Journal) getStore(); + + try { + + RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); + + RWStore rw = bufferStrategy.getRWStore(); + long numAllocs = rw.getTotalAllocations(); + long startAllocations = rw.getTotalAllocationsSize(); + long faddr = allocBatch(rw, 1000, 275, 320); + faddr = allocBatch(rw, 10000, 90, 128); + faddr = allocBatch(rw, 20000, 45, 64); + + System.out.println("Final allocation: " + faddr + ", allocations: " + + (rw.getTotalAllocations() - numAllocs) + ", allocated bytes: " + + (rw.getTotalAllocationsSize() - startAllocations)); + + store.commit(); + + // Confirm that we can re-open the journal after commit + store = (Journal) reopenStore(store); + + } finally { + + store.destroy(); + + } + + } + + /** + * Not so much a test as a code coverage exercise. + * + * The output from showAllocReserve confirms the relative merits of + * optimising for space vs density. The DirectFixedAllocators will + * allocate from DirectBuffers, where locality of reference is less + * important than efficient management of the memory, which is optimised + * by allocations in smaller amounts that match the demands at a finer + * granularity. + */ + public void testAllocationReserves() { + final int cReserve16K = 16 * 1024; + final int cReserve128K = 32 * 1024; + + showAllocReserve(false, 64, cReserve16K, cReserve16K); + showAllocReserve(false, 128, cReserve16K, cReserve16K); + showAllocReserve(false, 1024, cReserve16K, cReserve16K); + showAllocReserve(false, 2048, cReserve16K, cReserve16K); + showAllocReserve(false, 3072, cReserve16K, cReserve16K); + showAllocReserve(false, 4096, cReserve16K, cReserve16K); + showAllocReserve(false, 8192, cReserve16K, cReserve16K); + + showAllocReserve(true, 64, cReserve128K, cReserve16K); + showAllocReserve(true, 128, cReserve128K, cReserve16K); + showAllocReserve(true, 1024, cReserve128K, cReserve16K); + showAllocReserve(true, 2048, cReserve128K, cReserve16K); + showAllocReserve(true, 3072, cReserve128K, cReserve16K); + showAllocReserve(true, 4096, cReserve128K, cReserve16K); + showAllocReserve(true, 8192, cReserve128K, cReserve16K); + } + + private void showAllocReserve(final boolean optDensity, final int slotSize, final int reserve, final int mod) { + final int ints = FixedAllocator.calcBitSize(optDensity, slotSize, reserve, mod); + // there are max 254 ints available to a FixedAllocator + final int maxuse = (254 / (ints + 1)) * ints; + System.out.println("Allocate " + ints + ":" + (32 * ints * slotSize) + " for " + slotSize + " in " + + reserve + " using " + maxuse + " of 254 possible"); + } + + long allocBatch(RWStore rw, int bsize, int asze, int ainc) { + long curAddress = rw.physicalAddress(rw.alloc(asze, null)); + for (int i = 1; i < bsize; i++) { + int a = rw.alloc(asze, null); + long nxt = rw.physicalAddress(a); + assertTrue("Problem with index: " + i, diff(curAddress, nxt) == ainc || (nxt % 8192 == 0)); + curAddress = nxt; + } + + return curAddress; + } + + int diff(final long cur, final long nxt) { + int ret = (int) (nxt - cur); + return ret < 0 ? -ret : ret; + } + + int[] allocBatchBuffer(RWStore rw, int bsize, int base, int scope) { + int[] retaddrs = new int[bsize]; + + byte[] batchBuffer = new byte[base + scope]; + r.nextBytes(batchBuffer); + for (int i = 0; i < bsize; i++) { + int as = base + r.nextInt(scope); + retaddrs[i] = (int) rw.alloc(batchBuffer, as, null); + } + + return retaddrs; + } + + /** + * Reallocation tests the freeing of allocated address and the re-use + * within a transaction. + * + * The repeated runs with full reopening of the store check the + * initialization of the allocators on reload. + * + * @throws IOException + */ + public void test_reallocation() throws IOException { + final Properties properties = getProperties(); + File tmpfile = File.createTempFile("TestRW", "rw"); + properties.setProperty(Options.FILE, tmpfile.getAbsolutePath()); + properties.remove(Options.CREATE_TEMP_FILE); + Journal store = new Journal(properties); + + try { + + RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); + + RWStore rw = bufferStrategy.getRWStore(); + long numAllocs = rw.getTotalAllocations(); + long startAllocations = rw.getTotalAllocationsSize(); + + reallocBatch(rw, 1000, 275, 1000); + + store.commit(); + store.close(); + store = new Journal(properties); + bufferStrategy = (RWStrategy) store.getBufferStrategy(); + rw = bufferStrategy.getRWStore(); + + reallocBatch(rw, 1000, 100, 10000); + + store.commit(); + store.close(); + store = new Journal(properties); + bufferStrategy = (RWStrategy) store.getBufferStrategy(); + rw = bufferStrategy.getRWStore(); + + reallocBatch(rw, 1000, 100, 10000); + + store.commit(); + store.close(); + store = new Journal(properties); + bufferStrategy = (RWStrategy) store.getBufferStrategy(); + rw = bufferStrategy.getRWStore(); + + System.out.println("Final allocations: " + (rw.getTotalAllocations() - numAllocs) + + ", allocated bytes: " + (rw.getTotalAllocationsSize() - startAllocations) + ", file length: " + + rw.getStoreFile().length()); + } finally { + + store.destroy(); + + } + + } + + private long reallocBatch(RWStore rw, int tsts, int sze, int grp) { + long[] addr = new long[grp]; + for (int i = 0; i < grp; i++) { + addr[i] = rw.alloc(2 + r.nextInt(sze), null); + } + for (int t = 0; t < tsts; t++) { + for (int i = 0; i < grp; i++) { + long old = addr[i]; + int asze = 2 + r.nextInt(sze); + addr[i] = rw.alloc(asze, null); + + if (i % 2 == 0) + rw.free(old, 1); // dunno what the real size is + } + } + + return 0L; + } + + public void test_reallocationWithReadAndReopen() { + + Journal store = (Journal) getStore(); + + try { + + RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); + + RWStore rw = bufferStrategy.getRWStore(); + final int tcount = 2000; // increase to ramp up stress levels long numAllocs = rw.getTotalAllocations(); long startAllocations = rw.getTotalAllocationsSize(); // reallocBatchWithRead(bufferStrategy, 100000, 275, 5); - reallocBatchWithRead(store, 1, 100, 250, tcount, true, true); + reallocBatchWithRead(store, 1, 100, 250, tcount, true, true); store.close(); - + // added to try and foce bug System.out.println("Re-open Journal"); store = (Journal) getStore(); reallocBatchWithRead(store, 1, 800, 1500, tcount, true, true); reallocBatchWithRead(store, 1, 50, 250, tcount, true, true); - reallocBatchWithRead(store, 1, 50, 250, tcount, true, true); + reallocBatchWithRead(store, 1, 50, 250, tcount, true, true); store.close(); // .. end add to force bug - + System.out.println("Re-open Journal"); store = (Journal) getStore(); reallocBatchWithRead(store, 1, 2000, 10000, tcount, true, true); @@ -676,7 +689,7 @@ store = (Journal) getStore(); reallocBatchWithRead(store, 1, 800, 1256, tcount, true, true); reallocBatchWithRead(store, 1, 50, 250, tcount, true, true); - reallocBatchWithRead(store, 1, 50, 250, tcount, true, true); + reallocBatchWithRead(store, 1, 50, 250, tcount, true, true); showStore(store); store.close(); System.out.println("Re-open Journal"); @@ -699,88 +712,87 @@ } finally { store.destroy(); - - } - - } - - void showStore(Journal store) { - RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); + } + } + + void showStore(Journal store) { + RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); + RWStore rw = bufferStrategy.getRWStore(); - System.out.println("Fixed Allocators: " + rw.getFixedAllocatorCount() - + ", heap allocated: " + rw.getFileStorage() - + ", utilised bytes: " + rw.getAllocatedSlots() - + ", file length: " + rw.getStoreFile().length()); + System.out.println("Fixed Allocators: " + rw.getFixedAllocatorCount() + ", heap allocated: " + + rw.getFileStorage() + ", utilised bytes: " + rw.getAllocatedSlots() + ", file length: " + + rw.getStoreFile().length()); - } - - // Only realloc 1/5 - byte allocChar = 0; - private long reallocBatchWithRead(Journal store, int tsts, int min, int sze, int grp, boolean commit, boolean reopen) { - allocChar = (byte) (allocChar+1); - - RWStrategy bs = (RWStrategy) store - .getBufferStrategy(); + } - byte[] buf = new byte[sze+4]; // extra for checksum - // r.nextBytes(buf); - for (int i = 0; i < buf.length; i++) { - buf[i] = allocChar; - } - - - RWStore rw = bs.getRWStore(); - - long[] addr = new long[grp/5]; - int[] szes = new int[grp]; - for (int i = 0; i < grp; i++) { - szes[i] = min + r.nextInt(sze-min); - ByteBuffer bb = ByteBuffer.wrap(buf, 0, szes[i]); - if (i % 5 == 0) - addr[i/5] = bs.write(bb); - } - - if (commit) { - store.commit(); - } - - for (int t = 0; t < tsts; t++) { - for (int i = 0; i < (grp/5); i++) { - long old = addr[i]; - try { - bs.read(old); - } catch (Exception e) { - throw new RuntimeException("problem handling read: " + i + " in test: " + t + " from address: " + old, e); - } - ByteBuffer bb = ByteBuffer.wrap(buf, 0, szes[i]); - addr[i] = bs.write(bb); - bb.flip(); - bs.delete(old); - } - } - - if (commit) { - store.commit(); - - if (reopen) - rw.reset(); - - } - return 0L; + // Only realloc 1/5 + byte allocChar = 0; + + private long reallocBatchWithRead(Journal store, int tsts, int min, int sze, int grp, boolean commit, + boolean reopen) { + allocChar = (byte) (allocChar + 1); + + RWStrategy bs = (RWStrategy) store.getBufferStrategy(); + + byte[] buf = new byte[sze + 4]; // extra for checksum + // r.nextBytes(buf); + for (int i = 0; i < buf.length; i++) { + buf[i] = allocChar; + } + + RWStore rw = bs.getRWStore(); + + long[] addr = new long[grp / 5]; + int[] szes = new int[grp]; + for (int i = 0; i < grp; i++) { + szes[i] = min + r.nextInt(sze - min); + ByteBuffer bb = ByteBuffer.wrap(buf, 0, szes[i]); + if (i % 5 == 0) + addr[i / 5] = bs.write(bb); + } + + if (commit) { + store.commit(); + } + + for (int t = 0; t < tsts; t++) { + for (int i = 0; i < (grp / 5); i++) { + long old = addr[i]; + try { + bs.read(old); + } catch (Exception e) { + throw new RuntimeException("problem handling read: " + i + " in test: " + t + " from address: " + + old, e); + } + ByteBuffer bb = ByteBuffer.wrap(buf, 0, szes[i]); + addr[i] = bs.write(bb); + bb.flip(); + bs.delete(old); + } + } + + if (commit) { + store.commit(); + + if (reopen) + rw.reset(); + + } + return 0L; } - /** - * Adjust tcount to increase stress levels - */ - public void test_stressReallocationWithRead() { - - Journal store = (Journal) getStore(); + /** + * Adjust tcount to increase stress levels + */ + public void test_stressReallocationWithRead() { - try { + Journal store = (Journal) getStore(); + try { + final int tcount = 2000; // increase to ramp up stress levels RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); @@ -790,16 +802,16 @@ long numAllocs = rw.getTotalAllocations(); long startAllocations = rw.getTotalAllocationsSize(); // reallocBatchWithRead(bufferStrategy, 100000, 275, 5); - reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); - - reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); - reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); + reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); + reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); + reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); + reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); reallocBatchWithRead(store, 1, 800, 1500, tcount, false, false); reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); - reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); + reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); // Extend file with sizeable allocations reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); @@ -807,14 +819,14 @@ reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); - + reallocBatchWithRead(store, 1, 250, 500, tcount, false, false); reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); reallocBatchWithRead(store, 1, 800, 1256, tcount, false, false); reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); - reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); + reallocBatchWithRead(store, 1, 50, 250, tcount, false, false); reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); @@ -829,296 +841,295 @@ reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); reallocBatchWithRead(store, 1, 5000, 10000, tcount, false, false); - + reallocBatchWithRead(store, 1, 500, 1000, tcount, false, false); reallocBatchWithRead(store, 1, 1000, 2000, tcount, false, false); reallocBatchWithRead(store, 1, 500, 1000, tcount, false, false); - + store.commit(); - + showStore(store); - + store.close(); - + store = (Journal) getStore(); showStore(store); } finally { store.destroy(); - - } - - } + } - /** - * Test of blob allocation, does not check on read back, just the allocation - */ - public void test_blob_allocs() { - if (false) { - return; - } - - final Journal store = (Journal) getStore(); + } - try { + /** + * Test of blob allocation, does not check on read back, just the + * allocation + */ + public void test_blob_allocs() { + if (false) { + return; + } - RWStrategy bufferStrategy = (RWStrategy) store - .getBufferStrategy(); + final Journal store = (Journal) getStore(); - RWStore rw = bufferStrategy.getRWStore(); - long numAllocs = rw.getTotalAllocations(); - long startAllocations = rw.getTotalAllocationsSize(); - int startBlob = 1024 * 256; - int endBlob = 1024 * 1256; - int[] faddrs = allocBatchBuffer(rw, 100, startBlob, endBlob); - + try { + + RWStrategy bufferStrategy = (RWStrategy) store.getBufferStrategy(); + + RWStore rw = bufferStrategy.getRWStore(); + long numAllocs = rw.getTotalAllocations(); + long startAllocations = rw.getTotalAllocationsSize(); + int startBlob = 1024 * 256; + int endBlob = 1024 * 1256; + int[] faddrs = allocBatchBuffer(rw, 100, startBlob, endBlob); + final StringBuilder str = new StringBuilder(); rw.getStorageStats().showStats(str); - System.out.println(str); - } finally { + System.out.println(str); + } finally { - store.destroy(); - - } - - } - /** - * Test of blob allocation and read-back, firstly from cache and then from disk. - */ - public void test_blob_readBack() { - - final Journal store = (Journal) getStore(); + store.destroy(); - try { - final RWStrategy bs = (RWStrategy) store - .getBufferStrategy(); + } - final RWStore rw = bs.getRWStore(); - + } - byte[] buf = new byte[2 * 1024 * 1024]; // 5Mb buffer of random data - r.nextBytes(buf); - - ByteBuffer bb = ByteBuffer.wrap(buf); + /** + * Test of blob allocation and read-back, firstly from cache and then + * from disk. + */ + public void test_blob_readBack() { - long faddr = bs.write(bb); // rw.alloc(buf, buf.length); - - log.info("Blob Allocation at " + rw.convertFromAddr(faddr)); - - bb.position(0); - - ByteBuffer rdBuf = bs.read(faddr); - - assertEquals(bb, rdBuf); - - System.out.println("Now commit to disk"); - - store.commit(); - - // Now reset - clears writeCache and reinits from disk - rw.reset(); - - rdBuf = bs.read(faddr); - assertEquals(bb, rdBuf); + final Journal store = (Journal) getStore(); - } finally { + try { + final RWStrategy bs = (RWStrategy) store.getBufferStrategy(); - store.destroy(); - - } - - } - - /** - * Test of blob allocation and read-back, firstly from cache and then from disk. - * @throws InterruptedException - */ - public void test_blob_realloc() throws InterruptedException { - - final Journal store = (Journal) getStore(); + final RWStore rw = bs.getRWStore(); - try { + byte[] buf = new byte[2 * 1024 * 1024]; // 5Mb buffer of random + // data + r.nextBytes(buf); - final byte[] buf = new byte[1024 * 2048]; // 2Mb buffer of random data - r.nextBytes(buf); - - final ByteBuffer bb = ByteBuffer.wrap(buf); + ByteBuffer bb = ByteBuffer.wrap(buf); - final RWStrategy bs = (RWStrategy) store - .getBufferStrategy(); + long faddr = bs.write(bb); // rw.alloc(buf, buf.length); - final RWStore rw = bs.getRWStore(); - - long faddr = bs.write(bb); // rw.alloc(buf, buf.length); - - bb.position(0); - - ByteBuffer rdBuf = bs.read(faddr); - - assertEquals(bb, rdBuf); - - // now delete the memory - bs.delete(faddr); - - // verify immediateFree! - assertEquals(0L,bs.getPhysicalAddress(faddr)); - - // allocate another address, might (or might not) be the same. - faddr = bs.write(bb); // rw.alloc(buf, buf.length); - final long pa = bs.getPhysicalAddress(faddr); - bb.position(0); - - System.out.println("Now commit to disk (1)"); - - store.commit(); - - // Now reset - clears writeCache and reinits from disk - rw.reset(); - - rdBuf = bs.read(faddr); - assertEquals(bb, rdBuf); + log.info("Blob Allocation at " + rw.convertFromAddr(faddr)); - // now delete the memory - bs.delete(faddr); + bb.position(0); - // Must not have been immediately freed if history is retained. - if (rw.getHistoryRetention() != 0) - assertEquals(pa, bs.getPhysicalAddress(faddr)); - else - assertEquals(0L, bs.getPhysicalAddress(faddr)); - + ByteBuffer rdBuf = bs.read(faddr); - /* - * Commit before testing for deferred frees. Since there is a - * prior commit point, we are not allowed to immediately free - * any record from that commit point in order to preserve the - * consistency of the last commit point, so we have to commit - * first then test for deferred frees. - */ - System.out.println("Now commit to disk (2)"); - - store.commit(); - - Thread.currentThread().sleep(10); - - // Request release of deferred frees. - rw.checkDeferredFrees(true/* freeNow */, store); + assertEquals(bb, rdBuf); - assertEquals(0L, bs.getPhysicalAddress(faddr)); + System.out.println("Now commit to disk"); - try { - rdBuf = bs.read(faddr); // should fail with illegal argument - throw new RuntimeException("Fail"); - } catch (Exception ise) { - assertTrue("Expected IllegalArgumentException reading from " + (faddr >> 32) + " instead got: " + ise, ise instanceof IllegalArgumentException); - } - - } finally { + store.commit(); - store.destroy(); - - } - - } + // Now reset - clears writeCache and reinits from disk + rw.reset(); - + rdBuf = bs.read(faddr); + assertEquals(bb, rdBuf); + + } finally { + + store.destroy(); + + } + + } + /** - * Ttest write() + flush() + update() - for this case the data have been - * flushed from the write cache so the update will be a random write on - * the file rather than being buffered by the write cache. - */ - public void test_write_flush_update() { - - final Journal store = (Journal) getStore(); + * Test of blob allocation and read-back, firstly from cache and then + * from disk. + * + * @throws InterruptedException + */ + public void test_blob_realloc() throws InterruptedException { - try { + final Journal store = (Journal) getStore(); - RWStrategy bufferStrategy = (RWStrategy) store - .getBufferStrategy(); + try { - final int nbytes = 60; + final byte[] buf = new byte[1024 * 2048]; // 2Mb buffer of + // random data + r.nextBytes(buf); - // random data. - byte[] a = new byte[nbytes]; - r.nextBytes(a); - - // write a new record. - final long addr = bufferStrategy.write(ByteBuffer.wrap(a)); + final ByteBuffer bb = ByteBuffer.wrap(buf); - assertEquals(nbytes, store.getByteCount(addr)); - - // Note: This will result flush the write cache. - store.commit(); - - /* - * Read back the record and verify the update is visible. - */ - { - - final ByteBuffer b = bufferStrategy.read(addr); - - assertNotNull(b); - - for(int i=20; i<40; i++) { - - assertEquals("data differs at offset=" + i, a[i], b - .get(i)); - - } - - } - - } finally { + final RWStrategy bs = (RWStrategy) store.getBufferStrategy(); - store.destroy(); - - } + final RWStore rw = bs.getRWStore(); - } + long faddr = bs.write(bb); // rw.alloc(buf, buf.length); - public void test_metaAlloc() { - - Journal store = (Journal) getStore(); + bb.position(... [truncated message content] |