Leveldb for Java:迭代时删除

时间:2013-02-26 12:22:56

标签: leveldb

我正在运行此测试:

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?

2 个答案:

答案 0 :(得分:1)

事实证明,如果我在删除线程中调用next()之前调用iterator.seekToFirst(),它的行为与我期望的一样。 接下来的问题是,如果我不寻找某个位置,迭代器指向的地方。

答案 1 :(得分:1)

正如您在使用迭代器时所观察到的那样,您必须在迭代之前将迭代器指向seekToFirst或seekToLast的有效行。

我之前发现过这种情况(很难),它没有像你预期的那样抛出ISE,你只是得到不一致的读数。