/**
* Copyright 2011-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;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* Bug 790709 This happened on-site at XXX with the halo release. The server
* process was running with assertions enabled. The DELETE statement that failed
* was: DELETE FROM online_search where profileID = NAME_CONST('iUID',22162961)
* <p />
* The trace that showed up in the server log was:
*
* <code><pre>
*
* The trace that showed up in the server log was:
*
* WARN [Network-Worker-Thread-17] 2011-05-27 19:17:11,110 DefaultRequestHandler.java (line 70) Caught class java.lang.AssertionError on execution of DeleteRowRequest(18) rowData=online_search(22162961,'N','Y','Y','Y','N','N','N','N','N','N','N','Y','N','Y','N','N','N','Y','Y','Y','Y','Y','Y','N','N','N','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N','N','N','N','N','N','N','Y','Y','N','N','N','N','N','Y','N','N','N','N','N','Y','N','N','N','Y','N','N','N','N','N','N','N','Y','N','N','N','Y','N','N','Y','N','N','N','N','N','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',176,18,,,'0','2011-05-23 08:23:41','1','1','',1,2000435160,2000435248,755240,51.2666667000,0.5166667000,3,'N','N','Jakebarrett',79,42,62,8900192270,,,1)
* java.lang.AssertionError
* at com.persistit.FastIndex.putEbc(FastIndex.java:66)
* at com.persistit.FastIndex.recompute(FastIndex.java:137)
* at com.persistit.Buffer.findKey(Buffer.java:758)
* at com.persistit.Exchange.searchLevel(Exchange.java:112
* ...
* </pre></code>
* <p />
* The cause is a page left with more than _maxKeys keys in it, and that happens
* in REBALANCE case in Buffer.join(). There is no code in the rebalance case to
* limit the rebalanced pages to the maximum number of keys.
* <p />
*
*/
public class Bug790709Test extends PersistitUnitTestCase {
/*
* This test fails prior to bug fix.
*/
@Test
public void testRebalancePages1() throws Exception {
final Exchange ex = _persistit.getExchange("persistit", "Bug790709Test", true);
final int maxKeys = ex.getVolume().getPool().getMaxKeys();
//
// Create maxKeys keys in each of two pages. (There are
// two because when we add the maxKey+1th key, the page
// must split.
//
// On the second page the keys are a tad longer. The
// asymmetry is
//
for (int i = 0; i <= maxKeys; i++) {
ex.clear().append("a").append(i).store();
}
for (int i = 0; i <= maxKeys; i++) {
ex.clear().append("b").append(i).append("x").store();
}
ex.clear().append("a");
Buffer buffer1 = ex.fetchBufferCopy(0);
// System.out.println(buffer1 + " keys=" + buffer1.getKeyCount());
assertTrue(buffer1.getKeyCount() <= maxKeys);
ex.append("z");
Buffer buffer2 = ex.fetchBufferCopy(0);
// System.out.println(buffer2 + " keys=" + buffer2.getKeyCount());
assertTrue(buffer2.getKeyCount() <= maxKeys);
buffer2.getRecords()[0].getKeyState().copyTo(ex.getKey());
ex.remove();
ex.clear().append("a");
buffer1 = ex.fetchBufferCopy(0);
// System.out.println(buffer1 + " keys=" + buffer1.getKeyCount());
assertTrue(buffer1.getKeyCount() <= maxKeys);
ex.append("z");
buffer2 = ex.fetchBufferCopy(0);
// System.out.println(buffer2 + " keys=" + buffer2.getKeyCount());
assertTrue(buffer2.getKeyCount() <= maxKeys);
assertNotSame(buffer1, buffer2);
}
/*
* This test succeeds prior to bug fix.
*/
@Test
public void testRebalancePages2() throws Exception {
final Exchange ex = _persistit.getExchange("persistit", "Bug790709Test", true);
final int maxKeys = ex.getVolume().getPool().getMaxKeys();
//
// Create maxKeys keys in each of two pages. (There are
// two because when we add the maxKey+1th key, the page
// must split.
//
// On the second page the keys are a tad longer. The
// asymmetry is
//
for (int i = 0; i <= maxKeys; i++) {
ex.clear().append("a").append(i).append("x").store();
}
for (int i = 0; i <= maxKeys; i++) {
ex.clear().append("b").append(i).store();
}
ex.clear().append("a");
Buffer buffer1 = ex.fetchBufferCopy(0);
System.out.println(buffer1 + " keys=" + buffer1.getKeyCount());
assertTrue(buffer1.getKeyCount() <= maxKeys);
ex.append("z");
Buffer buffer2 = ex.fetchBufferCopy(0);
System.out.println(buffer2 + " keys=" + buffer2.getKeyCount());
assertTrue(buffer2.getKeyCount() <= maxKeys);
buffer2.getRecords()[0].getKeyState().copyTo(ex.getKey());
ex.remove();
ex.clear().append("a");
buffer1 = ex.fetchBufferCopy(0);
System.out.println(buffer1 + " keys=" + buffer1.getKeyCount());
assertTrue(buffer1.getKeyCount() <= maxKeys);
ex.append("z");
buffer2 = ex.fetchBufferCopy(0);
System.out.println(buffer2 + " keys=" + buffer2.getKeyCount());
assertTrue(buffer2.getKeyCount() <= maxKeys);
assertNotSame(buffer1, buffer2);
}
@Override
public void runAllTests() throws Exception {
// TODO Auto-generated method stub
}
}