/** * 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.stress.unit; import java.util.Arrays; import com.persistit.Key; import com.persistit.Value; import com.persistit.exception.PersistitException; import com.persistit.util.ArgParser; /** * A basic test sequence: * * 1. Delete all to clean * * 2. Sequential Fixed-length set/get/traverse/reverse traverse/remove * * 3. Child key insert / traverse / reverse /remove * * 4. Sequential Replacement / Elongation / Shortening * * 5. Random insertion / replacement / elongation / shortening * * 6. Long records insert / grow / shrink / remove * * 7. Spotty removes * * 8. Key range remove * */ public abstract class Stress4Base extends StressBase { protected final static String[] ARGS_TEMPLATE = { "repeat|int:1:0:1000000000|Repetitions", "count|int:10000:0:1000000000|Number of nodes to populate", "seed|int:1:1:20000|Random seed", "splay|int:1:1:1000|Splay", }; private int[] _checksum; protected int _splay; protected int _seed; private Exception _mostRecentException; public Stress4Base(final String argsString) { super(argsString); } @Override public void setUp() throws Exception { super.setUp(); _ap = new ArgParser("com.persistit.Stress4", _args, ARGS_TEMPLATE).strict(); _total = _ap.getIntValue("count"); _repeatTotal = _ap.getIntValue("repeat"); _total = _ap.getIntValue("count"); _seed = _ap.getIntValue("seed"); _splay = _ap.getIntValue("splay"); try { // Exchange with Thread-private Tree _ex = getPersistit().getExchange("persistit", _rootName + _threadIndex, true); _exs = getPersistit().getExchange("persistit", "shared", true); } catch (final Exception ex) { handleThrowable(ex); } } public abstract void repeatedTasks() throws PersistitException; @Override public void executeTest() { try { _checksum = new int[_total]; setPhase("@"); try { _ex.clear().remove(Key.GTEQ); } catch (final Exception e) { handleThrowable(e); } for (_repeat = 0; (_repeat < _repeatTotal || isUntilStopped()) && !isStopped(); _repeat++) { repeatedTasks(); } } catch (final Throwable t) { handleThrowable(t); } } public void clean() throws PersistitException { _ex.clear().remove(); Arrays.fill(_checksum, 0); } public boolean testReads(final int to) throws PersistitException { setPhase("f"); for (_count = 0; (_count < _total) && (_count < to) && !isStopped(); _count++) { _ex.clear().append(_count).fetch(); final int cksum = checksum(_ex.getValue()); if (cksum != _checksum[_count]) { return false; } } return true; } public boolean testForward() throws PersistitException { setPhase("a"); _ex.clear().append(Key.BEFORE); int index1 = 0; int index2; while (_ex.next() && !isStopped()) { index2 = (int) (_ex.getKey().decodeLong()); for (int i = index1; i < index2; i++) { if (_checksum[i] != -1) { return false; } } index1 = index2 + 1; final int cksum = checksum(_ex.getValue()); if ((index2 < 0) || (index2 >= _total)) { return false; } if (cksum != _checksum[index2]) { return false; } } for (int i = index1; i < _total; i++) { if (_checksum[i] != -1) { return false; } } return true; } public boolean testReverse() throws PersistitException { setPhase("b"); _ex.clear().append(Key.AFTER); int index1 = _total - 1; int index2; while (_ex.previous() && !isStopped()) { index2 = (int) (_ex.getKey().decodeLong()); for (int i = index1; i > index2; i--) { if (_checksum[i] != -1) { return false; } } index1 = index2 - 1; final int cksum = checksum(_ex.getValue()); if ((index2 < 0) || (index2 >= _total)) { return false; } if (cksum != _checksum[index2]) { return false; } } for (int i = index1; i >= 0; i--) { if (_checksum[i] != -1) { return false; } } return true; } public void writeRecords(final int to, final boolean random, final int minsize, final int maxsize) throws PersistitException { setPhase("w"); for (_count = 0; (_count < to) && !isStopped(); _count++) { int keyInteger; if (random) { keyInteger = keyInteger(_count); } else { keyInteger = _count; } _ex.clear().append(keyInteger); int size = minsize; if (minsize != maxsize) { size = random(minsize, maxsize); } setupTestValue(_ex, _count, size); _ex.store(); addWork(1); _checksum[keyInteger] = checksum(_ex.getValue()); } } public void readRecords(final int to, final boolean random, final int minsize, final int maxsize) throws PersistitException { final Value value1 = _ex.getValue(); final Value value2 = new Value(getPersistit()); setPhase("r"); for (_count = 0; (_count < to) && !isStopped(); _count++) { int keyInteger; if (random) { keyInteger = keyInteger(_count); } else { keyInteger = _count; } _ex.clear().append(keyInteger); int size = minsize; if (minsize != maxsize) { size = random(minsize, maxsize); } setupTestValue(_ex, _count, size); // fetch to a different Value object so we can compare // with the original. _ex.fetch(value2); addWork(1); compareValues(value1, value2); } } public void removeRecords(final int to, final boolean random) throws PersistitException { setPhase("d"); for (_count = 0; (_count < _total) && (_count < to) && !isStopped(); _count++) { int keyInteger; if (random) { keyInteger = keyInteger(_count); } else { keyInteger = _count; } _ex.clear().append(keyInteger); _ex.remove(); addWork(1); _checksum[keyInteger] = -1; } } public void writeLongKey(final int keyInteger, final int length, final int valueSize) throws PersistitException { } public void readLongKey(final int keyInteger, final int length, final int valueSize) throws PersistitException { } public void removeLongKey(final int keyInteger, final int length) throws PersistitException { } public void sleep() { try { Thread.sleep(1000); } catch (final Exception e) { } } int keyInteger(final int counter) { int keyInteger = (counter * _splay) % _total; if (keyInteger < 0) { keyInteger += _total; } return keyInteger; } }