blob: 0798c22b1dd717c681897161695fc03034ba8181 [file] [log] [blame]
/*
* Copyright 2009-2010 by The Regents of the University of California
* 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 from
*
* 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 edu.uci.ics.hyracks.storage.am.btree;
import java.io.DataOutput;
import java.io.File;
import java.nio.ByteBuffer;
import java.util.Random;
import org.junit.Assert;
import org.junit.Test;
import edu.uci.ics.hyracks.api.comm.IFrameTupleAccessor;
import edu.uci.ics.hyracks.api.context.IHyracksStageletContext;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.dataflow.value.ITypeTrait;
import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
import edu.uci.ics.hyracks.api.dataflow.value.TypeTrait;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.io.FileReference;
import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAppender;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.FrameTupleReference;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.dataflow.common.data.comparators.IntegerBinaryComparatorFactory;
import edu.uci.ics.hyracks.dataflow.common.data.marshalling.IntegerSerializerDeserializer;
import edu.uci.ics.hyracks.storage.am.btree.api.IBTreeTupleWriter;
import edu.uci.ics.hyracks.storage.am.btree.api.IPrefixSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.frames.FieldPrefixNSMLeafFrame;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTreeException;
import edu.uci.ics.hyracks.storage.am.btree.impls.FieldPrefixSlotManager;
import edu.uci.ics.hyracks.storage.am.btree.impls.MultiComparator;
import edu.uci.ics.hyracks.storage.am.btree.tuples.TypeAwareTupleWriter;
import edu.uci.ics.hyracks.storage.common.buffercache.IBufferCache;
import edu.uci.ics.hyracks.storage.common.buffercache.ICacheMemoryAllocator;
import edu.uci.ics.hyracks.storage.common.buffercache.ICachedPage;
import edu.uci.ics.hyracks.storage.common.file.BufferedFileHandle;
import edu.uci.ics.hyracks.storage.common.file.IFileMapProvider;
import edu.uci.ics.hyracks.test.support.TestStorageManagerComponentHolder;
import edu.uci.ics.hyracks.test.support.TestUtils;
public class BTreeFieldPrefixNSMTest {
private static final int PAGE_SIZE = 32768; // 32K
private static final int NUM_PAGES = 40;
private static final int HYRACKS_FRAME_SIZE = 128;
private String tmpDir = System.getProperty("java.io.tmpdir");
// to help with the logger madness
private void print(String str) {
System.out.print(str);
// if(GlobalConfig.ASTERIX_LOGGER.isLoggable(Level.FINEST)) {
// GlobalConfig.ASTERIX_LOGGER.finest(str);
// }
}
public class BufferAllocator implements ICacheMemoryAllocator {
@Override
public ByteBuffer[] allocate(int pageSize, int numPages) {
ByteBuffer[] buffers = new ByteBuffer[numPages];
for (int i = 0; i < numPages; ++i) {
buffers[i] = ByteBuffer.allocate(pageSize);
}
return buffers;
}
}
private ITupleReference createTuple(IHyracksStageletContext ctx, int f0, int f1, int f2, boolean print)
throws HyracksDataException {
if (print)
System.out.println("CREATING: " + f0 + " " + f1 + " " + f2);
ByteBuffer buf = ctx.allocateFrame();
FrameTupleAppender appender = new FrameTupleAppender(ctx.getFrameSize());
ArrayTupleBuilder tb = new ArrayTupleBuilder(3);
DataOutput dos = tb.getDataOutput();
ISerializerDeserializer[] recDescSers = { IntegerSerializerDeserializer.INSTANCE,
IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
RecordDescriptor recDesc = new RecordDescriptor(recDescSers);
IFrameTupleAccessor accessor = new FrameTupleAccessor(ctx.getFrameSize(), recDesc);
accessor.reset(buf);
FrameTupleReference tuple = new FrameTupleReference();
tb.reset();
IntegerSerializerDeserializer.INSTANCE.serialize(f0, dos);
tb.addFieldEndOffset();
IntegerSerializerDeserializer.INSTANCE.serialize(f1, dos);
tb.addFieldEndOffset();
IntegerSerializerDeserializer.INSTANCE.serialize(f2, dos);
tb.addFieldEndOffset();
appender.reset(buf, true);
appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize());
tuple.reset(accessor, 0);
return tuple;
}
@Test
public void test01() throws Exception {
IHyracksStageletContext stageletCtx = TestUtils.create(HYRACKS_FRAME_SIZE);
TestStorageManagerComponentHolder.init(PAGE_SIZE, NUM_PAGES);
IBufferCache bufferCache = TestStorageManagerComponentHolder.getBufferCache(stageletCtx);
IFileMapProvider fmp = TestStorageManagerComponentHolder.getFileMapProvider(stageletCtx);
FileReference file = new FileReference(new File(tmpDir + "/" + "btreetest.bin"));
bufferCache.createFile(file);
int fileId = fmp.lookupFileId(file);
bufferCache.openFile(fileId);
// declare fields
int fieldCount = 3;
ITypeTrait[] typeTraits = new ITypeTrait[fieldCount];
typeTraits[0] = new TypeTrait(4);
typeTraits[1] = new TypeTrait(4);
typeTraits[2] = new TypeTrait(4);
// declare keys
int keyFieldCount = 3;
IBinaryComparator[] cmps = new IBinaryComparator[keyFieldCount];
cmps[0] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
cmps[1] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
cmps[2] = IntegerBinaryComparatorFactory.INSTANCE.createBinaryComparator();
MultiComparator cmp = new MultiComparator(typeTraits, cmps);
// just for printing
ISerializerDeserializer[] sers = { IntegerSerializerDeserializer.INSTANCE,
IntegerSerializerDeserializer.INSTANCE, IntegerSerializerDeserializer.INSTANCE };
Random rnd = new Random();
rnd.setSeed(50);
ICachedPage page = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, 0), false);
try {
IPrefixSlotManager slotManager = new FieldPrefixSlotManager();
IBTreeTupleWriter tupleWriter = new TypeAwareTupleWriter(typeTraits);
FieldPrefixNSMLeafFrame frame = new FieldPrefixNSMLeafFrame(tupleWriter);
frame.setPage(page);
frame.initBuffer((byte) 0);
slotManager.setFrame(frame);
frame.setPrefixTupleCount(0);
String before = new String();
String after = new String();
int compactFreq = 5;
int compressFreq = 5;
int smallMax = 10;
int numRecords = 1000;
int[][] savedFields = new int[numRecords][3];
// insert records with random calls to compact and compress
for (int i = 0; i < numRecords; i++) {
if ((i + 1) % 100 == 0)
print("INSERTING " + (i + 1) + " / " + numRecords + "\n");
int a = rnd.nextInt() % smallMax;
int b = rnd.nextInt() % smallMax;
int c = i;
ITupleReference tuple = createTuple(stageletCtx, a, b, c, false);
try {
frame.insert(tuple, cmp);
} catch (BTreeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
savedFields[i][0] = a;
savedFields[i][1] = b;
savedFields[i][2] = c;
if (rnd.nextInt() % compactFreq == 0) {
before = frame.printKeys(cmp, sers);
frame.compact(cmp);
after = frame.printKeys(cmp, sers);
Assert.assertEquals(before, after);
}
if (rnd.nextInt() % compressFreq == 0) {
before = frame.printKeys(cmp, sers);
frame.compress(cmp);
after = frame.printKeys(cmp, sers);
Assert.assertEquals(before, after);
}
}
// delete records with random calls to compact and compress
for (int i = 0; i < numRecords; i++) {
if ((i + 1) % 100 == 0)
print("DELETING " + (i + 1) + " / " + numRecords + "\n");
ITupleReference tuple = createTuple(stageletCtx, savedFields[i][0], savedFields[i][1],
savedFields[i][2], false);
try {
frame.delete(tuple, cmp, true);
} catch (Exception e) {
}
if (rnd.nextInt() % compactFreq == 0) {
before = frame.printKeys(cmp, sers);
frame.compact(cmp);
after = frame.printKeys(cmp, sers);
Assert.assertEquals(before, after);
}
if (rnd.nextInt() % compressFreq == 0) {
before = frame.printKeys(cmp, sers);
frame.compress(cmp);
after = frame.printKeys(cmp, sers);
Assert.assertEquals(before, after);
}
}
} finally {
bufferCache.unpin(page);
}
bufferCache.closeFile(fileId);
bufferCache.close();
}
}