我正在运行此测试:
public class LeveldbTest {
@Test
public void test() throws IOException, InterruptedException {
DBFactory factory = new Iq80DBFactory();
Options opts = new Options();
opts.cacheSize(4096);
opts.compressionType(CompressionType.SNAPPY);
opts.createIfMissing(true).writeBufferSize(4096);
final DB db = factory.open(new File("target/leveldb"), opts);
final AtomicLong counter = new AtomicLong();
long start = System.currentTimeMillis();
new Thread() {
@Override
public void run() {
WriteOptions wo = new WriteOptions();
wo.sync(true);
while (true) {
String key = UUID.randomUUID().toString();
byte[] bytes = key.getBytes();
System.out.println("putting: " + key);
db.put(bytes, bytes, wo);
counter.incrementAndGet();
}
}
}.start();
new Thread() {
@Override
public void run() {
WriteOptions wo = new WriteOptions();
ReadOptions ro = new ReadOptions();
wo.sync(true);
while (true) {
DBIterator iterator = db.iterator(ro);
if (iterator.hasNext()) {
Entry<byte[], byte[]> next = iterator.next();
byte[] key = next.getKey();
System.out.println("deleting: " + new String(key));
db.delete(key, wo);
counter.incrementAndGet();
try {
iterator.close();
} catch (IOException e) {
}
}
}
}
}.start();
Thread.sleep(3000);
System.out.println((double) counter.longValue() / (System.currentTimeMillis() - start));
}
}
我希望密钥会从队列中删除,但在控制台中只会删除同一个密钥:
putting: a1ad4662-18c3-4085-af9d-a451dc3279c0
deleting: 004ef0c2-b278-42c6-9c85-4769d93d5b30 <-
putting: 6c4ee31d-2910-4870-acc5-962f9c40a573
deleting: 004ef0c2-b278-42c6-9c85-4769d93d5b30 <-
deleting: 004ef0c2-b278-42c6-9c85-4769d93d5b30 <-
putting: 63e2e438-3849-46e3-9ea0-1165f9356efb
deleting: 004ef0c2-b278-42c6-9c85-4769d93d5b30 <-
我是否错误地使用了API?
答案 0 :(得分:1)
事实证明,如果我在删除线程中调用next()之前调用iterator.seekToFirst(),它的行为与我期望的一样。 接下来的问题是,如果我不寻找某个位置,迭代器指向的地方。
答案 1 :(得分:1)
正如您在使用迭代器时所观察到的那样,您必须在迭代之前将迭代器指向seekToFirst或seekToLast的有效行。
我之前发现过这种情况(很难),它没有像你预期的那样抛出ISE,你只是得到不一致的读数。