/**
* Copyright 2013-2014 Recruit Technologies Co., Ltd. and contributors
* (see CONTRIBUTORS.md)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. A copy of the
* License is distributed with this work in the LICENSE.md file. You may
* also 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 org.gennai.gungnir.tuple.store;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import mockit.Mock;
import mockit.MockUp;
import mockit.integration.junit4.JMockit;
import org.gennai.gungnir.tuple.store.RocksDBTable.Entry;
import org.gennai.gungnir.tuple.store.RocksDBTable.EntryIterator;
import org.gennai.gungnir.tuple.store.RocksDBTable.SeekIterator;
import org.gennai.gungnir.utils.GungnirUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.rocksdb.RocksDBException;
import com.google.common.collect.Lists;
@RunWith(JMockit.class)
public class TestRocksDBTable {
@Test
public void testIterator() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put("aaa", 3, new byte[] {1, 1, 1});
table.put("aaa", 1, new byte[] {2, 2, 2});
table.put("bbb", 1, new byte[] {3, 3, 3});
table.put("aaa", 1, new byte[] {4, 4, 4});
table.put("aaa", 2, new byte[] {5, 5, 5});
table.put("ccc", 2, new byte[] {6, 6, 6});
table.put("aaa", 3, new byte[] {7, 7, 7});
table.put("bbb", 3, new byte[] {8, 8, 8});
table.put("aaa", 5, new byte[] {9, 9, 9});
table.put("ccc", 1, new byte[] {10, 10, 10});
assertThat(table.size(), is(10));
assertThat(table.size("aaa"), is(6));
assertThat(table.isEmpty(), is(false));
byte[][] expected = {
{2, 2, 2},
{4, 4, 4},
{5, 5, 5},
{1, 1, 1},
{7, 7, 7},
{9, 9, 9}
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(10));
assertThat(table.size("aaa"), is(6));
assertThat(table.isEmpty("aaa"), is(false));
assertThat(table.size("bbb"), is(2));
assertThat(table.isEmpty("bbb"), is(false));
expected = new byte[][] {
{2, 2, 2},
{4, 4, 4},
{5, 5, 5}
};
i = 0;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 3) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
} else {
break;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(7));
assertThat(table.size("aaa"), is(3));
assertThat(table.isEmpty("aaa"), is(false));
assertThat(table.size("bbb"), is(2));
assertThat(table.isEmpty("bbb"), is(false));
expected = new byte[][] {
{1, 1, 1},
{7, 7, 7},
{9, 9, 9}
};
i = 0;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 6) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
} else {
break;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(4));
assertThat(table.size("aaa"), is(0));
assertThat(table.isEmpty("aaa"), is(true));
assertThat(table.size("bbb"), is(2));
assertThat(table.isEmpty("bbb"), is(false));
expected = new byte[][] {
{3, 3, 3}
};
i = 0;
try {
for (it = table.iterator("bbb"); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 2) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
} else {
break;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(3));
assertThat(table.size("bbb"), is(1));
assertThat(table.isEmpty("bbb"), is(false));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testIterator2() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put(Lists.newArrayList("aaa", "bbb"), 3, new byte[] {1, 1});
table.put(Lists.newArrayList("aaa", "bbb"), 1, new byte[] {2, 2});
table.put(Lists.newArrayList("aaa", "bbb", "ccc"), 1, new byte[] {3, 3});
table.put(Lists.newArrayList("aaa", "bbb"), 1, new byte[] {4, 4});
table.put(Lists.newArrayList("aaa", "bbb"), 2, new byte[] {5, 5});
table.put(Lists.newArrayList("aaa", "bb2"), 2, new byte[] {6, 6});
table.put(Lists.newArrayList("aaa", "bbb"), 3, new byte[] {7, 7});
table.put(Lists.newArrayList("aaa", "bbb", "ccc"), 3, new byte[] {8, 8});
table.put(Lists.newArrayList("aaa", "bbb"), 5, new byte[] {9, 9});
assertThat(table.size(), is(9));
assertThat(table.size(Lists.newArrayList("aaa", "bbb")), is(6));
assertThat(table.isEmpty(), is(false));
byte[][] expected = {
{2, 2},
{4, 4},
{5, 5},
{1, 1},
{7, 7},
{9, 9}
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator(Lists.newArrayList("aaa", "bbb")); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(9));
assertThat(table.size(Lists.newArrayList("aaa", "bbb")), is(6));
assertThat(table.isEmpty(Lists.newArrayList("aaa", "bbb")), is(false));
expected = new byte[][] {
{2, 2},
{4, 4},
{5, 5}
};
i = 0;
try {
for (it = table.iterator(Lists.newArrayList("aaa", "bbb")); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 3) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
} else {
break;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(6));
assertThat(table.size(Lists.newArrayList("aaa", "bbb")), is(3));
assertThat(table.isEmpty(Lists.newArrayList("aaa", "bbb")), is(false));
expected = new byte[][] {
{1, 1},
{7, 7},
{9, 9}
};
i = 0;
try {
for (it = table.iterator(Lists.newArrayList("aaa", "bbb")); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 6) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
} else {
break;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(3));
assertThat(table.size(Lists.newArrayList("aaa", "bbb")), is(0));
assertThat(table.isEmpty(Lists.newArrayList("aaa", "bbb")), is(true));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testIterator3() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put(3, new byte[] {1});
table.put(1, new byte[] {2});
table.put(1, new byte[] {3});
table.put(3, new byte[] {4});
table.put(2, new byte[] {5});
table.put(2, new byte[] {6});
assertThat(table.size(), is(6));
byte[][] expected = {
{2},
{3},
{5},
{6}
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 3) {
assertThat(entry.getValue(), is(expected[i]));
i++;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(6));
expected = new byte[][] {
{2},
{3},
{5},
{6}
};
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 3) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(2));
expected = new byte[][] {
{1},
{4}
};
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 5) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testIterator4() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.incr("aaa", 2);
table.incr("aaa", 1);
table.incr("bbb", 2);
table.incr("aaa", 2);
table.incr("aaa", 1);
table.incr("aaa", 5);
table.incr("aaa", 2);
table.incr("bbb", 5);
table.incr("aaa", 1);
table.incr("aaa", 2);
table.incr("bbb", 5);
table.incr("aaa", 5);
table.incr("bbb", 5);
table.incr("aaa", 1);
table.incr("aaa", 2);
table.incr("aaa", 5);
table.incr("ccc", 4);
table.incr("aaa", 4);
assertThat(table.size(), is(18));
assertThat(table.size("aaa"), is(13));
assertThat(table.isEmpty(), is(false));
byte[][] expected = {
{0, 0, 0, 4},
{0, 0, 0, 5}
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 4) {
assertThat(entry.getValue(), is(expected[i]));
i++;
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(18));
assertThat(table.size("aaa"), is(13));
assertThat(table.isEmpty(), is(false));
expected = new byte[][] {
{0, 0, 0, 4},
{0, 0, 0, 5}
};
i = 0;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 4) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(9));
assertThat(table.size("aaa"), is(4));
assertThat(table.isEmpty("aaa"), is(false));
table.close();
GungnirUtils.deleteDirectory(dbPath);
dbPath = Files.createTempDirectory("gungnirdb");
table = RocksDBTable.open(dbPath.toString());
table.incr(3);
table.incr(1);
table.incr(2);
table.incr(1);
table.incr(2);
table.incr(1);
assertThat(table.size(), is(6));
expected = new byte[][] {
{0, 0, 0, 3},
{0, 0, 0, 2}
};
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 3) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(1));
expected = new byte[][] {
{0, 0, 0, 1}
};
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
if (entry.getTimeKey() < 4) {
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testIterator5() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put("aaa", 3, new byte[] {1, 1, 1});
table.put("aaa", 1, new byte[] {2, 2, 2});
table.put("bbb", 1, new byte[] {3, 3, 3});
table.put("aaa", 1, new byte[] {4, 4, 4});
table.put("aaa", 2, new byte[] {5, 5, 5});
table.put("ccc", 2, new byte[] {6, 6, 6});
table.put("aaa", 3, new byte[] {7, 7, 7});
table.put("bbb", 3, new byte[] {8, 8, 8});
table.put("aaa", 5, new byte[] {9, 9, 9});
table.put("ccc", 1, new byte[] {10, 10, 10});
byte[][] expected = {
{2, 2, 2},
{4, 4, 4},
{5, 5, 5},
{1, 1, 1},
{7, 7, 7},
{9, 9, 9},
{3, 3, 3},
{8, 8, 8},
{10, 10, 10},
{6, 6, 6}
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(0));
table.incr("aaa", 2);
table.incr("aaa", 1);
table.incr("bbb", 2);
table.incr("aaa", 2);
table.incr("aaa", 1);
table.incr("aaa", 5);
table.incr("aaa", 2);
table.incr("bbb", 5);
table.incr("aaa", 1);
table.incr("aaa", 2);
table.incr("bbb", 5);
table.incr("aaa", 5);
table.incr("bbb", 5);
table.incr("aaa", 1);
table.incr("aaa", 2);
table.incr("aaa", 5);
table.incr("ccc", 4);
table.incr("aaa", 4);
expected = new byte[][] {
{0, 0, 0, 4},
{0, 0, 0, 5},
{0, 0, 0, 1},
{0, 0, 0, 3},
{0, 0, 0, 1},
{0, 0, 0, 3},
{0, 0, 0, 1}
};
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
it.remove();
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testRemoveFirst() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put("aaa", 3, new byte[] {1, 1, 1});
table.put("aaa", 1, new byte[] {2, 2, 2});
table.put("bbb", 1, new byte[] {3, 3, 3});
table.put("aaa", 1, new byte[] {4, 4, 4});
table.put("aaa", 2, new byte[] {5, 5, 5});
table.put("ccc", 2, new byte[] {6, 6, 6});
table.put("aaa", 3, new byte[] {7, 7, 7});
table.put("bbb", 3, new byte[] {8, 8, 8});
table.put("aaa", 5, new byte[] {9, 9, 9});
table.put("ccc", 1, new byte[] {10, 10, 10});
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {2, 2, 2}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {4, 4, 4}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {5, 5, 5}));
assertThat(table.size(), is(7));
assertThat(table.size("aaa"), is(3));
assertThat(table.isEmpty("aaa"), is(false));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {1, 1, 1}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {7, 7, 7}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {9, 9, 9}));
assertThat(table.size(), is(4));
assertThat(table.size("aaa"), is(0));
assertThat(table.isEmpty("aaa"), is(true));
assertThat(table.removeFirst("aaa"), nullValue());
assertThat(table.removeFirst("bbb").getValue(), is(new byte[] {3, 3, 3}));
assertThat(table.removeFirst("bbb").getValue(), is(new byte[] {8, 8, 8}));
assertThat(table.removeFirst("ccc").getValue(), is(new byte[] {10, 10, 10}));
assertThat(table.removeFirst("ccc").getValue(), is(new byte[] {6, 6, 6}));
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testRemoveFirst2() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put(Lists.newArrayList("aaa", "bbb"), 3, new byte[] {1, 1});
table.put(Lists.newArrayList("aaa", "bbb"), 1, new byte[] {2, 2});
table.put(Lists.newArrayList("aaa", "bbb", "ccc"), 1, new byte[] {3, 3});
table.put(Lists.newArrayList("aaa", "bbb"), 1, new byte[] {4, 4});
table.put(Lists.newArrayList("aaa", "bbb"), 2, new byte[] {5, 5});
table.put(Lists.newArrayList("aaa", "bb2"), 2, new byte[] {6, 6});
table.put(Lists.newArrayList("aaa", "bbb"), 3, new byte[] {7, 7});
table.put(Lists.newArrayList("aaa", "bbb", "ccc"), 3, new byte[] {8, 8});
table.put(Lists.newArrayList("aaa", "bbb"), 5, new byte[] {9, 9});
assertThat(table.removeFirst(Lists.newArrayList("aaa", "bbb")).getValue(),
is(new byte[] {2, 2}));
assertThat(table.removeFirst(Lists.newArrayList("aaa", "bbb")).getValue(),
is(new byte[] {4, 4}));
assertThat(table.removeFirst(Lists.newArrayList("aaa", "bbb")).getValue(),
is(new byte[] {5, 5}));
assertThat(table.size(), is(6));
assertThat(table.size(Lists.newArrayList("aaa", "bbb")), is(3));
assertThat(table.isEmpty(Lists.newArrayList("aaa", "bbb")), is(false));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testRemoveFirst3() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put(3, new byte[] {1});
table.put(1, new byte[] {2});
table.put(1, new byte[] {3});
table.put(3, new byte[] {4});
table.put(2, new byte[] {5});
table.put(2, new byte[] {6});
assertThat(table.removeFirst().getValue(), is(new byte[] {2}));
assertThat(table.removeFirst().getValue(), is(new byte[] {3}));
assertThat(table.removeFirst().getValue(), is(new byte[] {5}));
assertThat(table.size(), is(3));
assertThat(table.removeFirst().getValue(), is(new byte[] {6}));
assertThat(table.removeFirst().getValue(), is(new byte[] {1}));
assertThat(table.removeFirst().getValue(), is(new byte[] {4}));
assertThat(table.removeFirst(), nullValue());
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
private Entry seekEntry;
private void seek(RocksDBTable table, int expireSec, int seekSize, Object[][] expected)
throws RocksDBException {
SeekIterator it = table.seekIterator();
try {
if (seekEntry == null) {
it.seekToFirst();
} else {
it.seek(seekEntry.getHashKey(), seekEntry.getTimeKey(), seekEntry.getSeqNo(),
false);
if (!it.isValid()) {
it.seekToFirst();
}
}
int j = 0;
for (int i = 0; it.isValid() && i < seekSize; i++) {
Entry entry = it.entry();
seekEntry = entry;
if (entry.getTimeKey() < expireSec) {
assertThat(entry.getHashKey(), is(expected[j][0]));
assertThat(entry.getTimeKey(), is(expected[j][1]));
assertThat(entry.getValue(), is(expected[j][2]));
j++;
it.remove();
it.next();
} else {
entry.setTimeKey(Integer.MAX_VALUE);
entry.setSeqNo(Integer.MAX_VALUE);
it.seek(entry.getHashKey(), entry.getTimeKey(), entry.getSeqNo(), false);
}
}
if (expected != null) {
assertThat(j, is(expected.length));
} else {
assertThat(j, is(0));
}
} finally {
it.close();
}
}
@Test
public void testSeekIterator() throws Exception {
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString());
table.put("aaa", 3, new byte[] {1, 1, 1});
table.put("aaa", 1, new byte[] {2, 2, 2});
table.put("bbb", 1, new byte[] {3, 3, 3});
table.put("aaa", 1, new byte[] {4, 4, 4});
table.put("aaa", 2, new byte[] {5, 5, 5});
table.put("ccc", 2, new byte[] {6, 6, 6});
table.put("aaa", 3, new byte[] {7, 7, 7});
table.put("bbb", 3, new byte[] {8, 8, 8});
table.put("aaa", 5, new byte[] {9, 9, 9});
table.put("ccc", 1, new byte[] {10, 10, 10});
seekEntry = null;
seek(table, 1, 8, null);
Object[][] expected = {
{"aaa", 1, new byte[] {2, 2, 2}},
{"aaa", 1, new byte[] {4, 4, 4}},
{"bbb", 1, new byte[] {3, 3, 3}},
{"ccc", 1, new byte[] {10, 10, 10}}
};
seek(table, 2, 8, expected);
seek(table, 2, 8, null);
table.put("aaa", 4, new byte[] {11, 11, 11});
table.put("ddd", 3, new byte[] {12, 12, 12});
table.put("bbb", 3, new byte[] {13, 13, 13});
table.put("bbb", 3, new byte[] {14, 14, 14});
expected = new Object[][] {
{"ddd", 3, new byte[] {12, 12, 12}}
};
seek(table, 4, 8, expected);
expected = new Object[][] {
{"aaa", 2, new byte[] {5, 5, 5}},
{"aaa", 3, new byte[] {1, 1, 1}},
{"aaa", 3, new byte[] {7, 7, 7}},
{"bbb", 3, new byte[] {8, 8, 8}}
};
seek(table, 4, 5, expected);
expected = new Object[][] {
{"bbb", 3, new byte[] {13, 13, 13}},
{"bbb", 3, new byte[] {14, 14, 14}},
{"ccc", 2, new byte[] {6, 6, 6}}
};
seek(table, 4, 5, expected);
expected = new Object[][] {
{"aaa", 4, new byte[] {11, 11, 11}},
{"aaa", 5, new byte[] {9, 9, 9}}
};
seek(table, 6, 5, expected);
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
// CHECKSTYLE IGNORE MethodLength FOR NEXT 1 LINES
@Test
public void testExpire() throws Exception {
final int now = GungnirUtils.currentTimeSecs();
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString(), 3, 4);
table.put("aaa", now + 3, new byte[] {1, 1, 1});
table.put("aaa", now + 1, new byte[] {2, 2, 2});
table.put("bbb", now + 1, new byte[] {3, 3, 3});
table.put("aaa", now + 1, new byte[] {4, 4, 4});
table.put("aaa", now + 2, new byte[] {5, 5, 5});
table.put("ccc", now + 2, new byte[] {6, 6, 6});
table.put("aaa", now + 3, new byte[] {7, 7, 7});
table.put("bbb", now + 3, new byte[] {8, 8, 8});
table.put("aaa", now + 5, new byte[] {9, 9, 9});
table.put("ccc", now + 1, new byte[] {10, 10, 10});
assertThat(table.size(), is(10));
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 6;
}
};
assertThat(table.size("aaa"), is(3));
assertThat(table.size("bbb"), is(1));
assertThat(table.size("ccc"), is(0));
assertThat(table.isEmpty("aaa"), is(false));
assertThat(table.isEmpty("bbb"), is(false));
assertThat(table.isEmpty("ccc"), is(true));
Object[][] expected = {
{"aaa", now + 6, new byte[] {1, 1, 1}},
{"aaa", now + 6, new byte[] {7, 7, 7}},
{"aaa", now + 8, new byte[] {9, 9, 9}},
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(10));
assertThat(table.removeFirst("bbb").getValue(), is(new byte[] {8, 8, 8}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {1, 1, 1}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {7, 7, 7}));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {9, 9, 9}));
assertThat(table.removeFirst("aaa"), nullValue());
assertThat(table.isEmpty("aaa"), is(true));
assertThat(table.isEmpty("bbb"), is(true));
assertThat(table.isEmpty("ccc"), is(true));
assertThat(table.size(), is(2));
expected = new Object[][] {
{"ccc", now + 4, new byte[] {10, 10, 10}},
{"ccc", now + 5, new byte[] {6, 6, 6}}
};
i = 0;
SeekIterator sit = table.seekIterator();
try {
for (sit.seekToFirst(); sit.isValid(); sit.next()) {
Entry entry = sit.entry();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
sit.remove();
}
} finally {
if (sit != null) {
sit.close();
sit = null;
}
}
assertThat(table.size(), is(0));
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now;
}
};
table.put(now + 3, new byte[] {1});
table.put(now + 1, new byte[] {2});
table.put(now + 1, new byte[] {3});
table.put(now + 3, new byte[] {4});
table.put(now + 2, new byte[] {5});
table.put(now + 2, new byte[] {6});
assertThat(table.size(), is(6));
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 6;
}
};
assertThat(table.size(), is(2));
expected = new Object[][] {
{null, now + 6, new byte[] {1}},
{null, now + 6, new byte[] {4}}
};
i = 0;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(table.removeFirst().getValue(), is(new byte[] {1}));
assertThat(table.removeFirst().getValue(), is(new byte[] {4}));
assertThat(table.removeFirst(), nullValue());
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
// CHECKSTYLE IGNORE MethodLength FOR NEXT 1 LINES
@Test
public void testCompactRange() throws Exception {
final int now = GungnirUtils.currentTimeSecs();
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString(), 3, 4);
table.compactRange();
table.put("aaa", now + 3, new byte[] {1, 1, 1});
table.put("aaa", now + 1, new byte[] {2, 2, 2});
table.put("bbb", now + 1, new byte[] {3, 3, 3});
table.put("aaa", now + 1, new byte[] {4, 4, 4});
table.put("aaa", now + 2, new byte[] {5, 5, 5});
table.put("ccc", now + 2, new byte[] {6, 6, 6});
table.put("aaa", now + 3, new byte[] {7, 7, 7});
table.put("bbb", now + 3, new byte[] {8, 8, 8});
table.put("aaa", now + 5, new byte[] {9, 9, 9});
table.put("ccc", now + 1, new byte[] {10, 10, 10});
assertThat(table.size(), is(10));
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 5;
}
};
Object[][] expected = {
{"aaa", now + 4, new byte[] {2, 2, 2}},
{"aaa", now + 4, new byte[] {4, 4, 4}},
{"bbb", now + 4, new byte[] {3, 3, 3}}
};
List<Entry> entries = table.compactRange();
int i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(7));
assertThat(table.size("aaa"), is(4));
assertThat(table.size("bbb"), is(1));
assertThat(table.size("ccc"), is(1));
assertThat(table.isEmpty("aaa"), is(false));
assertThat(table.isEmpty("bbb"), is(false));
assertThat(table.isEmpty("ccc"), is(false));
expected = new Object[][] {
{"aaa", now + 5, new byte[] {5, 5, 5}},
{"aaa", now + 6, new byte[] {1, 1, 1}},
{"aaa", now + 6, new byte[] {7, 7, 7}},
{"aaa", now + 8, new byte[] {9, 9, 9}}
};
i = 0;
EntryIterator it = null;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(7));
expected = new Object[][] {
{"ccc", now + 4, new byte[] {10, 10, 10}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(6));
assertThat(table.size("aaa"), is(4));
assertThat(table.size("bbb"), is(1));
assertThat(table.size("ccc"), is(1));
table.put("aaa", now + 4, new byte[] {11, 11, 11});
table.put("ddd", now + 3, new byte[] {12, 12, 12});
table.put("bbb", now + 3, new byte[] {13, 13, 13});
table.put("bbb", now + 3, new byte[] {14, 14, 14});
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 8;
}
};
expected = new Object[][] {
{"ddd", now + 6, new byte[] {12, 12, 12}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(9));
assertThat(table.size("aaa"), is(1));
assertThat(table.size("bbb"), is(0));
assertThat(table.size("ccc"), is(0));
assertThat(table.size("ddd"), is(0));
expected = new Object[][] {
{"aaa", now + 5, new byte[] {5, 5, 5}},
{"aaa", now + 6, new byte[] {1, 1, 1}},
{"aaa", now + 6, new byte[] {7, 7, 7}},
{"aaa", now + 7, new byte[] {11, 11, 11}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(5));
assertThat(table.removeFirst("aaa").getValue(), is(new byte[] {9, 9, 9}));
assertThat(table.removeFirst("aaa"), nullValue());
expected = new Object[][] {
{"bbb", now + 6, new byte[] {8, 8, 8}},
{"bbb", now + 6, new byte[] {13, 13, 13}},
{"bbb", now + 6, new byte[] {14, 14, 14}},
{"ccc", now + 5, new byte[] {6, 6, 6}}
};
i = 0;
SeekIterator sit = table.seekIterator();
try {
for (sit.seekToFirst(); sit.isValid(); sit.next()) {
Entry entry = sit.entry();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
} finally {
if (sit != null) {
sit.close();
sit = null;
}
}
assertThat(i, is(expected.length));
table.put("aaa", now + 10, new byte[] {15, 15, 15});
table.put("bbb", now + 10, new byte[] {16, 16, 16});
expected = new Object[][] {
{"bbb", now + 13, new byte[] {16, 16, 16}},
{"ccc", now + 5, new byte[] {6, 6, 6}},
{"aaa", now + 13, new byte[] {15, 15, 15}},
};
i = 0;
sit = table.seekIterator();
try {
for (sit.seekToFirst(); sit.isValid(); sit.next()) {
Entry entry = sit.entry();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
} finally {
if (sit != null) {
sit.close();
sit = null;
}
}
assertThat(i, is(expected.length));
entries = table.compactRange();
assertThat(entries.isEmpty(), is(true));
assertThat(table.size(), is(3));
expected = new Object[][] {
{"ccc", now + 5, new byte[] {6, 6, 6}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
entries = table.compactRange();
assertThat(entries.isEmpty(), is(true));
assertThat(table.size(), is(2));
assertThat(table.size("aaa"), is(1));
assertThat(table.size("bbb"), is(1));
assertThat(table.size("ccc"), is(0));
assertThat(table.size("ddd"), is(0));
expected = new Object[][] {
{"bbb", now + 13, new byte[] {16, 16, 16}},
{"aaa", now + 13, new byte[] {15, 15, 15}},
};
i = 0;
sit = table.seekIterator();
try {
for (sit.seekToFirst(); sit.isValid(); sit.next()) {
assertThat(sit.entry().getHashKey(), is(expected[i][0]));
assertThat(sit.entry().getTimeKey(), is(expected[i][1]));
assertThat(sit.entry().getValue(), is(expected[i][2]));
i++;
}
} finally {
if (sit != null) {
sit.close();
sit = null;
}
}
assertThat(i, is(expected.length));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testCompactRange2() throws Exception {
final int now = GungnirUtils.currentTimeSecs();
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString(), 3, 4);
table.compactRange();
table.incr("aaa", now + 2);
table.incr("aaa", now + 1);
table.incr("bbb", now + 2);
table.incr("aaa", now + 2);
table.incr("aaa", now + 1);
table.incr("aaa", now + 5);
table.incr("aaa", now + 2);
table.incr("bbb", now + 5);
table.incr("aaa", now + 1);
table.incr("aaa", now + 2);
table.incr("bbb", now + 5);
table.incr("aaa", now + 5);
table.incr("bbb", now + 5);
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 6;
}
};
Object[][] expected = {
{"aaa", now + 4, new byte[] {0, 0, 0, 3}},
{"aaa", now + 5, new byte[] {0, 0, 0, 4}},
{"bbb", now + 5, new byte[] {0, 0, 0, 1}},
};
List<Entry> entries = table.compactRange();
int i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(5));
table.incr("aaa", now + 1);
table.incr("aaa", now + 2);
table.incr("aaa", now + 5);
table.incr("ccc", now + 4);
table.incr("aaa", now + 4);
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 9;
}
};
expected = new Object[][] {
{"bbb", now + 8, new byte[] {0, 0, 0, 3}},
{"ccc", now + 7, new byte[] {0, 0, 0, 1}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(4));
expected = new Object[][] {
{"aaa", now + 7, new byte[] {0, 0, 0, 1}},
{"aaa", now + 8, new byte[] {0, 0, 0, 3}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testCompactRange3() throws Exception {
final int now = GungnirUtils.currentTimeSecs();
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString(), 3, 4);
table.compactRange();
table.put(now + 3, new byte[] {1});
table.put(now + 1, new byte[] {2});
table.put(now + 1, new byte[] {3});
table.put(now + 3, new byte[] {4});
table.put(now + 2, new byte[] {5});
table.put(now + 2, new byte[] {6});
assertThat(table.size(), is(6));
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 5;
}
};
Object[][] expected = {
{now + 4, new byte[] {2}},
{now + 4, new byte[] {3}}
};
List<Entry> entries = table.compactRange();
int i = 0;
for (Entry entry : entries) {
assertThat(entry.getTimeKey(), is(expected[i][0]));
assertThat(entry.getValue(), is(expected[i][1]));
i++;
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(4));
expected = new Object[][] {
{null, now + 5, new byte[] {5}},
{null, now + 5, new byte[] {6}},
{null, now + 6, new byte[] {1}},
{null, now + 6, new byte[] {4}}
};
i = 0;
EntryIterator it = null;
try {
for (it = table.iterator(); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getHashKey(), is(expected[i][0]));
assertThat(entry.getTimeKey(), is(expected[i][1]));
assertThat(entry.getValue(), is(expected[i][2]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
entries = table.compactRange();
assertThat(entries.isEmpty(), is(true));
table.put(now + 5, new byte[] {7});
table.put(now + 5, new byte[] {8});
assertThat(table.removeFirst().getValue(), is(new byte[] {5}));
entries = table.compactRange();
assertThat(entries.isEmpty(), is(true));
assertThat(table.removeFirst().getValue(), is(new byte[] {6}));
assertThat(table.removeFirst().getValue(), is(new byte[] {1}));
new MockUp<GungnirUtils>() {
@Mock
public int currentTimeSecs() {
return now + 10;
}
};
expected = new Object[][] {
{now + 6, new byte[] {4}},
{now + 8, new byte[] {7}},
{now + 8, new byte[] {8}}
};
entries = table.compactRange();
i = 0;
for (Entry entry : entries) {
assertThat(entry.getTimeKey(), is(expected[i][0]));
assertThat(entry.getValue(), is(expected[i][1]));
i++;
}
assertThat(table.size(), is(0));
} finally {
if (table != null) {
table.close();
}
GungnirUtils.deleteDirectory(dbPath);
}
}
@Test
public void testReOpen() throws Exception {
final int now = GungnirUtils.currentTimeSecs();
Path dbPath = Files.createTempDirectory("gungnirdb");
RocksDBTable table = null;
try {
table = RocksDBTable.open(dbPath.toString(), 3, 4);
table.put("aaa", now + 3, new byte[] {1, 1, 1});
table.put("aaa", now + 1, new byte[] {2, 2, 2});
table.put("bbb", now + 1, new byte[] {3, 3, 3});
table.put("aaa", now + 1, new byte[] {4, 4, 4});
table.put("aaa", now + 2, new byte[] {5, 5, 5});
table.put("ccc", now + 2, new byte[] {6, 6, 6});
table.put("aaa", now + 3, new byte[] {7, 7, 7});
table.put("bbb", now + 3, new byte[] {8, 8, 8});
table.put("aaa", now + 5, new byte[] {9, 9, 9});
table.put("ccc", now + 1, new byte[] {10, 10, 10});
} finally {
if (table != null) {
table.close();
table = null;
}
}
try {
table = RocksDBTable.open(dbPath.toString(), 3, 4);
byte[][] expected = {
{2, 2, 2},
{4, 4, 4},
{5, 5, 5},
{1, 1, 1},
{7, 7, 7},
{9, 9, 9}
};
int i = 0;
EntryIterator it = null;
try {
for (it = table.iterator("aaa"); it.hasNext();) {
Entry entry = it.next();
assertThat(entry.getValue(), is(expected[i]));
i++;
}
} finally {
if (it != null) {
it.close();
it = null;
}
}
assertThat(i, is(expected.length));
assertThat(table.size(), is(10));
assertThat(table.size("aaa"), is(6));
assertThat(table.isEmpty("aaa"), is(false));
assertThat(table.size("bbb"), is(2));
assertThat(table.isEmpty("bbb"), is(false));
} finally {
if (table != null) {
table.close();
table = null;
}
GungnirUtils.deleteDirectory(dbPath);
}
}
}