提交 7b346b46 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add ceilingKey() and floorKey() with tests

上级 56a3ab02
......@@ -1345,6 +1345,22 @@ public class TransactionStore {
return key;
}
/**
* Get the smallest key that is larger than or equal to this key,
* or null if no such key exists.
*
* @param key the key (may not be null)
* @return the result
*/
public K ceilingKey(K key) {
key = map.ceilingKey(key);
while (key != null && get(key) == null) {
// Use higherKey() for the next attempts, otherwise we'll get an infinite loop
key = higherKey(key);
}
return key;
}
/**
* Get one of the previous or next keys. There might be no value
* available for the returned key.
......@@ -1362,6 +1378,22 @@ public class TransactionStore {
return map.getKey(index + offset);
}
/**
* Get the largest key that is smaller than or equal to this key,
* or null if no such key exists.
*
* @param key the key (may not be null)
* @return the result
*/
public K floorKey(K key) {
key = map.floorKey(key);
while (key != null && get(key) == null) {
// Use lowerKey() for the next attempts, otherwise we'll get an infinite loop
key = lowerKey(key);
}
return key;
}
/**
* Get the largest key that is smaller than the given key, or null if no
* such key exists.
......
......@@ -19,9 +19,11 @@ import org.h2.mvstore.DataUtils;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVStore;
import org.h2.mvstore.db.TransactionStore;
import org.h2.mvstore.db.ValueDataType;
import org.h2.mvstore.db.TransactionStore.Change;
import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.db.TransactionStore.TransactionMap;
import org.h2.mvstore.type.ObjectDataType;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
import org.h2.util.New;
......@@ -44,6 +46,7 @@ public class TestTransactionStore extends TestBase {
@Override
public void test() throws Exception {
FileUtils.createDirectories(getBaseDir());
testHCLFKey();
testConcurrentAddRemove();
testConcurrentAdd();
testCountWithOpenTransactions();
......@@ -62,6 +65,48 @@ public class TestTransactionStore extends TestBase {
testStoreMultiThreadedReads();
}
private void testHCLFKey() {
MVStore s = MVStore.open(null);
final TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction t = ts.begin();
ObjectDataType keyType = new ObjectDataType();
TransactionMap<Long, Long> map = t.openMap("test", keyType, keyType);
map.put(10L, 100L);
map.put(20L, 200L);
map.put(30L, 300L);
map.put(40L, 400L);
t.commit();
t = ts.begin();
map = t.openMap("test", keyType, keyType);
map.put(15L, 150L);
// The same transaction
assertEquals((Object) 15L, map.higherKey(10L));
t = ts.begin();
map = t.openMap("test", keyType, keyType);
// Another transaction
// higherKey()
assertEquals((Object) 20L, map.higherKey(10L));
assertEquals((Object) 20L, map.higherKey(15L));
assertNull(map.higherKey(40L));
// ceilingKey()
assertEquals((Object) 10L, map.ceilingKey(10L));
assertEquals((Object) 20L, map.ceilingKey(15L));
assertEquals((Object) 40L, map.ceilingKey(40L));
assertNull(map.higherKey(45L));
// lowerKey()
assertNull(map.lowerKey(10L));
assertEquals((Object) 10L, map.lowerKey(15L));
assertEquals((Object) 10L, map.lowerKey(20L));
assertEquals((Object) 20L, map.lowerKey(25L));
// floorKey()
assertNull(map.floorKey(5L));
assertEquals((Object) 10L, map.floorKey(10L));
assertEquals((Object) 10L, map.floorKey(15L));
assertEquals((Object) 30L, map.floorKey(35L));
s.close();
}
private static void testConcurrentAddRemove() throws InterruptedException {
MVStore s = MVStore.open(null);
int threadCount = 3;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论