/** * Copyright 2005-2012 Akiban Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.persistit.unit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.Properties; import org.junit.Test; import com.persistit.Exchange; import com.persistit.Key; import com.persistit.PersistitUnitTestCase; import com.persistit.Value; import com.persistit.exception.PersistitException; public class SimpleTest1 extends PersistitUnitTestCase { private static String[] _args = new String[0]; private String _volumeName = "persistit"; @Test public void test1() throws PersistitException { store1(); fetch1a(); fetch1b(); fetch1c(); } private void checkEmpty() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", true); exchange.append(Key.BEFORE); final boolean empty = !exchange.traverse(Key.GT, true); assertTrue(empty); } private void store1() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", true); exchange.removeAll(); final StringBuilder sb = new StringBuilder(); for (int i = 1; i < 400; i++) { sb.setLength(0); sb.append((char) (i / 20 + 64)); sb.append((char) (i % 20 + 64)); exchange.clear().append(sb); exchange.getValue().put("Record #" + i); exchange.store(); } } private void remove1() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", true); exchange.removeAll(); final StringBuilder sb = new StringBuilder(); for (int i = 1; i < 400; i++) { sb.setLength(0); sb.append((char) (i / 20 + 64)); sb.append((char) (i % 20 + 64)); exchange.clear().append(sb); exchange.remove(); } } private void fetch1a() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", false); final StringBuilder sb = new StringBuilder(); for (int i = 1; i < 400; i++) { sb.setLength(0); sb.append((char) (i / 20 + 64)); sb.append((char) (i % 20 + 64)); exchange.clear().append(sb); exchange.fetch(); assertTrue(exchange.getValue().isDefined()); assertEquals("Record #" + i, exchange.getValue().getString()); } } private void fetch1b() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", false); final StringBuilder sb = new StringBuilder(); for (int i = 1; i < 400; i++) { sb.setLength(0); sb.append((char) (i % 20 + 64)); sb.append((char) (i / 20 + 64)); exchange.clear().append(sb); exchange.fetch(); final int k = (i / 20) + (i % 20) * 20; assertEquals(exchange.getValue().getString(), "Record #" + k); } } private void fetch1c() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", false); int count; exchange.getKey().clear().append(Key.BEFORE); final StringBuilder sb = new StringBuilder(); for (count = 1; exchange.next() && count < 10000; count++) { sb.setLength(0); sb.append((char) (count / 20 + 64)); sb.append((char) (count % 20 + 64)); final String key = exchange.getKey().reset().decodeString(); assertEquals(sb.toString(), key); } assertEquals(400, count); exchange.getKey().clear().append(Key.AFTER); for (count = 399; exchange.previous() && count > -10000; count--) { sb.setLength(0); sb.append((char) (count / 20 + 64)); sb.append((char) (count % 20 + 64)); final String key = exchange.getKey().reset().decodeString(); assertEquals(sb.toString(), key); } assertEquals(0, count); } @Test public void test2() throws PersistitException { store2(); fetch2(); } private void store2() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1LongRecord", true); exchange.getValue().setMaximumSize(32 * 1024 * 1024); final StringBuilder sb = new StringBuilder(); int length = 19; while (length < 10000000) { sb.setLength(0); sb.append(com.persistit.util.Util.format(length)); sb.append(" "); sb.setLength(length); // System.out.print("Record length " + length); exchange.getValue().put(sb.toString()); // System.out.print(" encoded: " // + exchange.getValue().getEncodedSize()); exchange.clear().append(length).store(); // System.out.println(" - stored"); length *= 2; } } private void fetch2() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1LongRecord", true); exchange.getValue().setMaximumSize(32 * 1024 * 1024); final StringBuilder sb = new StringBuilder(); final StringBuilder sb2 = new StringBuilder(); int length = 19; while (length < 10000000) { sb.setLength(0); sb.append(com.persistit.util.Util.format(length)); sb.append(" "); sb.setLength(length); // System.out.print("Record length " + length); exchange.clear().append(length).fetch(); sb2.setLength(0); exchange.getValue().getString(sb2); assertEquals(sb.toString(), sb2.toString()); // System.out.println(" - read"); length *= 2; } } @Test public void test3() throws PersistitException { // Tests fix for split calculation failure. // final StringBuilder sb = new StringBuilder(4000); final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1BadSplit", true); exchange.removeAll(); final Key key = exchange.getKey(); final Value value = exchange.getValue(); key.clear().append("A").append(1); setupString(sb, 3000); value.putString(sb); exchange.store(); key.clear().append("A").append(2); setupString(sb, 3000); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1566).append(3); setupString(sb, 119); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1568).append(4); setupString(sb, 2258); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1569).append(3); setupString(sb, 119); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1571).append(3); setupString(sb, 3052); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1573).append(3); setupString(sb, 119); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1573).append(4); setupString(sb, 2203); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1573).append(3); setupString(sb, 2524); value.putString(sb); exchange.store(); key.clear().append("stress2").append(1566).append(3); setupString(sb, 119); exchange.fetch(); assertEquals(sb.toString(), exchange.getValue().getString()); key.clear().append("stress2").append(1568).append(4); setupString(sb, 2258); exchange.fetch(); assertEquals(sb.toString(), exchange.getValue().getString()); key.clear().append("stress2").append(1569).append(3); setupString(sb, 119); exchange.fetch(); assertEquals(sb.toString(), exchange.getValue().getString()); key.clear().append("stress2").append(1571).append(3); setupString(sb, 3052); exchange.fetch(); assertEquals(sb.toString(), exchange.getValue().getString()); key.clear().append("stress2").append(1573).append(4); setupString(sb, 2203); exchange.fetch(); assertEquals(sb.toString(), exchange.getValue().getString()); key.clear().append("stress2").append(1573).append(3); setupString(sb, 2524); exchange.fetch(); assertEquals(sb.toString(), exchange.getValue().getString()); } @Test public void test4() throws PersistitException { // Tests join calculation. // final StringBuilder sb = new StringBuilder(4000); final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1BadJoin", true); exchange.removeAll(); final Key key = exchange.getKey(); final Value value = exchange.getValue(); key.clear().append("A").append(1); setupString(sb, 1000); value.putString(sb); exchange.store(); key.clear().append("A").append(2); setupString(sb, 1000); value.putString(sb); exchange.store(); key.clear().append("A").append(3); setupString(sb, 1000); value.putString(sb); exchange.store(); key.clear() .append("B") .append("... a pretty long key value. The goal is to get the the record " + "for this key into the penultimate slot of the left page, followed " + "by a short key on the edge. Then delete that short key, so that" + "this becomes the edge key."); setupString(sb, 10); value.putString(sb); exchange.store(); // Here's where we want the page to split... key.clear().append("B").append("z"); setupString(sb, 20); value.putString(sb); exchange.store(); key.clear().append("C").append(1); setupString(sb, 1000); value.putString(sb); exchange.store(); key.clear().append("C").append(2); setupString(sb, 1000); value.putString(sb); exchange.store(); for (int len = 1000; len < 2600; len += 100) { key.clear().append("A").append(1); setupString(sb, len); value.putString(sb); exchange.store(); key.clear().append("A").append(2); setupString(sb, len); value.putString(sb); exchange.store(); key.clear().append("A").append(3); setupString(sb, len); value.putString(sb); exchange.store(); key.clear().append("C").append(1); setupString(sb, len); value.putString(sb); exchange.store(); } // Now the page should be split with the {"B", "z"} on the edge. // Need an additional 4540 bytes, leaving 60 bytes free. key.clear().append("C").append(1); setupString(sb, 4040); // adds 1540 value.putString(sb); exchange.store(); key.clear().append("C").append(2); setupString(sb, 4040); // adds 1540 value.putString(sb); exchange.store(); key.clear().append("C").append(2); setupString(sb, 4040); // adds 1540 value.putString(sb); exchange.store(); key.clear().append("A").append(1); setupString(sb, 2500 + 356); value.putString(sb); exchange.store(); key.clear().append("A").append(1); exchange.fetch(); key.clear().append("B").append("z"); exchange.fetch(); key.clear().append("C").append(3); exchange.fetch(); key.clear().append("B").append("z"); exchange.remove(); // may cause wedge failure. } @Test public void test5() throws PersistitException { final StringBuilder sb = new StringBuilder(1024 * 1024 * 16); final StringBuilder sb2 = new StringBuilder(1024 * 1024 * 16); final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1BadStoreOverLengthRecord", true); exchange.removeAll(); final Key key = exchange.getKey(); final Value value = exchange.getValue(); value.setMaximumSize(1024 * 1024 * 32); key.clear().append("A").append(1); final int length = 8160 * 1024 * 2 + 1; // System.out.print(" " + length); setupString(sb, length); value.putString(sb); exchange.store(); exchange.fetch(); value.getString(sb2); final int length2 = sb2.length(); assertEquals(length, length2); assertTrue(sb.toString().equals(sb2.toString())); } @Test public void test6() throws PersistitException { final Exchange exchange = _persistit.getExchange(_volumeName, "SimpleTest1", true); exchange.removeAll(); exchange.getValue().put(RED_FOX); for (int i = 10000; --i >= 0;) { exchange.to(i).remove(); } for (int i = 0; i < 10000; i++) { exchange.to(i).store(); } for (int i = 0; i < 10000; i++) { exchange.to(i).remove(); } for (int i = 10000; --i >= 0;) { exchange.to(i).store(); } for (int i = 10000; --i >= 0;) { exchange.to(i).remove(); } } void setupString(final StringBuilder sb, final int length) { sb.setLength(length); final String s = "length=" + length; sb.replace(0, s.length(), s); for (int i = s.length(); i < length; i++) { sb.setCharAt(i, ' '); } } public static void pause(final String prompt) { System.out.print(prompt + " Press ENTER to continue"); System.out.flush(); try { while (System.in.read() != '\r') { } } catch (final IOException ioe) { } System.out.println(); } public static void main(final String[] args) throws Exception { _args = args; new SimpleTest1().initAndRunTest(); } @Override public Properties getProperties(final boolean cleanup) { return UnitTestProperties.getBiggerProperties(cleanup); } @Override public void runAllTests() throws Exception { String protocol = "none"; if (_args.length > 1) { for (int index = 1; index < _args.length; index++) { protocol = _args[index]; if (protocol.startsWith("p")) { _volumeName = "persistit"; } if (protocol.startsWith("t")) { _volumeName = "tempvol"; } System.out.println("SimpleTest1 protocol: " + protocol); if (protocol.equals("p")) { store1(); fetch1a(); fetch1b(); } else if (protocol.equals("p1")) { store1(); } else if (protocol.equals("p2")) { fetch1a(); fetch1b(); } else if (protocol.equals("t")) { store1(); fetch1a(); fetch1b(); } else if (protocol.equals("t1")) { store1(); } else if (protocol.equals("t2")) { checkEmpty(); } else { System.out.println("? " + protocol); } } } else { test1(); test2(); test3(); test4(); test5(); } } }