package com.github.believe3301.nonheapdb.test; import java.util.Arrays; import java.util.Random; import com.github.believe3301.nonheapdb.MemoryBuffer; import com.github.believe3301.nonheapdb.Record; import com.github.believe3301.nonheapdb.Util; import junit.framework.TestCase; import com.github.believe3301.nonheapdb.RecordIndex; public abstract class BasedTest extends TestCase { public BasedTest(final String name) { super(name); } public String generateKey(long n) { return String.format("%016d", n); } protected byte[] generateTestData(final int size) { byte[] data = new byte[size]; Random rand = new Random(); int start = 33 + rand.nextInt(95); for (int i = 0; i < size; i++) { data[i] = (byte) (((start + i) % 127) + 1); } return data; } protected void assertEqualContent(byte[] b1, byte[] b2) { if (b1 != null) { assertNotNull(b2); assertEquals("length mismatch", b1.length, b2.length); assertTrue("content mismatch", Arrays.equals(b1, b2)); } else { assertNull(b2); } } /** * 检查记录按照一定的格式存储 * @param buffer 内存缓冲区. 注意因为内存是共享的,所以不是指当前记录,通过这个内存缓冲区可以定位到任何一条记录 * @param rec 索引,可以获取capacity,offset * @param key 记录的key * @param value 记录的value */ protected void checkRecord(MemoryBuffer buffer, RecordIndex rec, byte[] key, byte[] value){ byte[] ksbuf = Util.writeVarInt(key.length); byte[] vsbuf = Util.writeVarInt(value.length); //kstep + vstep + 1 + ksize + vsize + 8 int capacity = ksbuf.length + vsbuf.length + 1 + key.length + value.length + 8; assertEquals(rec.capacity(), capacity); //每条记录的offset是一个MAGIC标记 TestCase.assertEquals(buffer.getData(rec.offset()), Record.MAGICREC); assertTrue(buffer.getLong(rec.offset() + 1) == 0L);//next //kstep assertEqualContent(buffer.getData(ksbuf.length, rec.offset() + 8 + 1), ksbuf); //vstep assertEqualContent(buffer.getData(vsbuf.length, rec.offset() + ksbuf.length + 8 + 1), vsbuf); //ksize assertEqualContent(buffer.getData(key.length, rec.offset() + ksbuf.length + vsbuf.length + 8 + 1), key); //vsize assertEqualContent(buffer.getData(value.length, rec.offset() + ksbuf.length + vsbuf.length + 8 + key.length + 1), value); } /** * 写一条记录 * @param buffer * @param key * @param value * @return */ protected RecordIndex writeRecord(MemoryBuffer buffer, byte[] key, byte[] value) { int used = buffer.used(); //新创建一条记录 Record rec = new Record(); rec.setData(value); rec.setKey(new String(key)); //将记录的字节数组添加到内存中的缓冲区中,返回这条记录的索引信息 RecordIndex ridx = buffer.putData(rec.getBuffer()); //索引记录了记录的容量=添加记录后的容量-添加记录前的容量 assertEquals(ridx.capacity(), buffer.used() - used); //检查这条记录是否按照指定的格式存入 checkRecord(buffer, ridx, key, value); return ridx; } protected void writeRecord(MemoryBuffer buffer, byte[] key, byte[] value, int offset) { Record rec = new Record(); rec.setData(value); rec.setKey(new String(key)); //在指定的位置将记录写入内存的缓冲区中 buffer.putData(rec.getBuffer(), offset); } }