package com.ctriposs.sdb.table;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import com.ctriposs.sdb.table.FCMapTable;
import com.ctriposs.sdb.table.GetResult;
import com.ctriposs.sdb.table.HashMapTable;
import com.ctriposs.sdb.utils.FileUtil;
import com.ctriposs.sdb.utils.TestUtil;
public class FCMapTableTest {
private static String testDir = TestUtil.TEST_BASE_DIR + "sdb/unit/level_2_table_test";
private FCMapTable mapTable;
@Test
public void testEmtpy() throws IOException, ClassNotFoundException {
long createdTime = System.nanoTime();
mapTable = new FCMapTable(testDir, 1, createdTime, 1000);
assertTrue(mapTable.getLevel() == 1);
assertTrue(mapTable.getCreatedTime() == createdTime);
assertTrue(mapTable.getAppendedSize() == 0);
assertTrue(mapTable.isEmpty());
assertTrue(mapTable.getBackFileSize() == HashMapTable.INIT_INDEX_FILE_SIZE + HashMapTable.INIT_DATA_FILE_SIZE + HashMapTable.INDEX_ITEM_LENGTH);
assertFalse(mapTable.isUsable());
try {
@SuppressWarnings("unused")
GetResult result = mapTable.get("empty".getBytes());
fail();
} catch (IllegalArgumentException iae) {
}
try {
mapTable.getMapEntry(-1);
fail();
} catch (IllegalArgumentException iae) {
}
try {
mapTable.getMapEntry(0);
} catch (IllegalArgumentException iae) {
}
}
@Test
public void testAppendAndGet() throws IOException, ClassNotFoundException {
long createdTime = System.nanoTime();
mapTable = new FCMapTable(testDir, 1, createdTime, 1000);
assertTrue(mapTable.getLevel() == 1);
assertTrue(mapTable.getCreatedTime() == createdTime);
assertTrue(mapTable.getAppendedSize() == 0);
assertTrue(mapTable.isEmpty());
assertTrue(mapTable.getBackFileSize() == HashMapTable.INIT_INDEX_FILE_SIZE + HashMapTable.INIT_DATA_FILE_SIZE + HashMapTable.INDEX_ITEM_LENGTH);
mapTable.appendNew("key".getBytes(), "value".getBytes(), 500);
assertTrue(mapTable.getLevel() == 1);
assertTrue(mapTable.getCreatedTime() == createdTime);
assertTrue(mapTable.getAppendedSize() == 1);
assertFalse(mapTable.isEmpty());
GetResult result = mapTable.get("key".getBytes());
assertTrue(result.isFound());
assertTrue(!result.isDeleted());
assertTrue(!result.isExpired());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
result = mapTable.get("key".getBytes());
assertTrue(result.isFound());
assertTrue(!result.isDeleted());
assertTrue(result.isExpired());
result = mapTable.get("key1".getBytes());
assertFalse(result.isFound());
assertFalse(mapTable.isUsable());
}
@Test
public void testLoopAndReopen() throws IOException, ClassNotFoundException {
long createdTime = System.nanoTime();
int loop = 32 * 1024;
mapTable = new FCMapTable(testDir, 1, createdTime, loop);
assertTrue(mapTable.getLevel() == 1);
assertTrue(mapTable.getCreatedTime() == createdTime);
assertTrue(mapTable.getAppendedSize() == 0);
assertTrue(mapTable.isEmpty());
assertTrue(mapTable.getBackFileSize() == HashMapTable.INIT_INDEX_FILE_SIZE + HashMapTable.INIT_DATA_FILE_SIZE + HashMapTable.INDEX_ITEM_LENGTH);
assertFalse(mapTable.isUsable());
List<byte[]> list = new ArrayList<byte[]>();
for(int i = 0; i < loop; i++) {
list.add(("key" + i).getBytes());
}
Collections.sort(list, new Comparator<byte[]>() {
@Override
public int compare(byte[] arg0, byte[] arg1) {
int hash0 = Arrays.hashCode(arg0);
int hash1 = Arrays.hashCode(arg1);
if (hash0 < hash1) return -1;
else if (hash0 > hash1) return 1;
else return 0;
}
});
for(int i = 0; i < loop; i++) {
mapTable.appendNew(list.get(i), ("value" + i).getBytes(), -1);
}
assertTrue(mapTable.getAppendedSize() == loop);
long start = System.currentTimeMillis();
for(int i = 0; i < loop; i++) {
GetResult result = mapTable.get(("key" + i).getBytes());
assertTrue(result.isFound());
}
long time = System.currentTimeMillis() - start;
System.out.printf("Get %,d K ops per second%n",
(int) (loop / time));
GetResult result = mapTable.get(("key" + loop).getBytes());
assertFalse(result.isFound());
assertFalse(result.isDeleted() || result.isExpired());
mapTable.markUsable(true);
mapTable.saveMetadata();
mapTable.close();
mapTable = new FCMapTable(testDir, mapTable.getFileName());
assertTrue(mapTable.isUsable());
assertTrue(mapTable.getAppendedSize() == loop);
for(int i = 0; i < loop; i++) {
result = mapTable.get(("key" + i).getBytes());
assertTrue(result.isFound());
}
result = mapTable.get(("key" + loop).getBytes());
assertFalse(result.isFound());
assertFalse(result.isDeleted() || result.isExpired());
mapTable.markUsable(false);
mapTable.saveMetadata();
mapTable.close();
mapTable = new FCMapTable(testDir, mapTable.getFileName());
assertFalse(mapTable.isUsable());
assertTrue(mapTable.getAppendedSize() == loop);
for(int i = 0; i < loop; i++) {
result = mapTable.get(("key" + i).getBytes());
assertTrue(result.isFound());
}
}
@Test
public void operationAfterClosedTest() throws Exception {
long createdTime = System.nanoTime();
mapTable = new FCMapTable(testDir, 1, createdTime, 1);
mapTable.close();
final byte[] testKey = new byte[]{1}, testValue = new byte[]{1};
try {
mapTable.appendNew(testKey, testValue, 1000);
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.appendNew(testKey, Arrays.hashCode(testKey), testValue, 1000, System.currentTimeMillis(), false, false);
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.getMapEntry(0);
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.reMap();
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.persistToAppendDataFileOffset();
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.persistToAppendIndex();
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.persistBloomFilter();
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
try {
mapTable.saveMetadata();
fail("Should not get here after the SDB is closed.");
} catch (IllegalStateException e) {
}
}
@After
public void clear() throws IOException {
if (mapTable != null) {
mapTable.close();
}
FileUtil.deleteDirectory(new File(testDir));
}
}