/** * 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.assertEquals; import java.util.Random; import org.junit.Test; import com.persistit.ValueHelper.RawValueWriter; public class FastIndexTest extends PersistitUnitTestCase { private Buffer getABuffer() throws Exception { final Exchange exchange = _persistit.getExchange("persistit", "FastIndexTest", true); return exchange.getBufferPool().get(exchange.getVolume(), 1, true, true); } @Test public void testIndexSize() throws Exception { final Buffer b1 = getABuffer(); try { final FastIndex fi = b1.getFastIndex(); /* * BUFFER_SIZE - HEADER_SIZE / MAX_KEY_RATIO BUFFER_SIZE = 16384 * HEADER_SIZE = 32 MAX_KEY_RATIO = 16 16384 - 32 / 16 = 16352 / 16 * = 1022 size passed to FastIndex constructor is 1022 + 1 when * parameters are as listed above. */ final int expectedSize = (16384 - Buffer.HEADER_SIZE) / Buffer.MAX_KEY_RATIO; assertEquals(expectedSize + 1, fi.size()); } finally { b1.release(); } } @Test public void testIndexValidity() throws Exception { final Buffer b1 = getABuffer(); try { b1.init(Buffer.PAGE_TYPE_GARBAGE); final FastIndex fi = b1.getFastIndex(); fi.invalidate(); assertEquals(false, fi.isValid()); fi.recompute(); assertEquals(false, fi.isValid()); b1.init(Buffer.PAGE_TYPE_DATA); fi.recompute(); assertEquals(true, fi.isValid()); assertEquals(true, fi.verify()); fi.invalidate(); assertEquals(false, fi.isValid()); assertEquals(false, fi.verify()); } finally { b1.release(); } } @Test public void testFastIndexRecompute() throws Exception { final Buffer b1 = getABuffer(); try { b1.init(Buffer.PAGE_TYPE_DATA); final Key key = new Key(_persistit); final Value value = new Value(_persistit); final RawValueWriter vwriter = new RawValueWriter(); final FastIndex fi = b1.getFastIndex(); fi.recompute(); vwriter.init(value); fakeKey(key, "A"); b1.putValue(key, vwriter); fakeKey(key, "ABC"); b1.putValue(key, vwriter); fakeKey(key, "ABK"); b1.putValue(key, vwriter); fakeKey(key, "ABZ"); b1.putValue(key, vwriter); fakeKey(key, "AC"); b1.putValue(key, vwriter); fakeKey(key, "C"); b1.putValue(key, vwriter); fakeKey(key, "B"); b1.putValue(key, vwriter); fakeKey(key, "E"); b1.putValue(key, vwriter); fakeKey(key, "D"); b1.putValue(key, vwriter); fakeKey(key, "DA"); b1.putValue(key, vwriter); fakeKey(key, "ABB"); b1.putValue(key, vwriter); fakeKey(key, "ABA"); b1.putValue(key, vwriter); fakeKey(key, "ABJ"); b1.putValue(key, vwriter); final String inserteds = fi.toString(); fi.recompute(); final String computeds = fi.toString(); assertEquals(inserteds, computeds); } finally { b1.release(); } } private void fakeKey(final Key key, final String v) { key.clear().append(v); System.arraycopy(key.getEncodedBytes(), 1, key.getEncodedBytes(), 0, key.getEncodedSize()); key.setEncodedSize(key.getEncodedSize() - 1); } @Test public void testRandomInsert() throws Exception { final Random random = new Random(3); final Buffer b1 = getABuffer(); try { final FastIndex f1 = b1.getFastIndex(); b1.init(Buffer.PAGE_TYPE_DATA); final Key key = new Key(_persistit); final Value value = new Value(_persistit); for (int i = 0; i < 1000; i++) { final int size = random.nextInt(10) + 2; final byte[] bytes = new byte[size]; random.nextBytes(bytes); System.arraycopy(bytes, 0, key.getEncodedBytes(), 0, size); key.setEncodedSize(size); final RawValueWriter vwriter = new RawValueWriter(); vwriter.init(value); b1.putValue(key, vwriter); final String s1 = f1.toString(); f1.recompute(); final String s2 = f1.toString(); assertEquals(s1, s2); } } finally { b1.release(); } } }