dain / leveldb

Port of LevelDB to Java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Last Entry in LevelDB remains

platacc opened this issue · comments

I am using .delete(key) to delete multiple entries in LevelDB. All entries are being deleted fine with no issues. However the first key I delete always results in just the value of the entry being deleted, and the key remains with "null" value.

Any ideas why this is happening every time?

DBIterator iterator = getTransactionDatabase().iterator();

    while (iterator.hasNext()) {
    Map.Entry<byte[], byte[]> next = iterator.next();

    try{
            getTransactionDatabase().delete(next.getKey());
    }

UPDATE: I am using Spring and when I close the application and restart, then the last value is gone entirely. But why is it not allowing an empty database during runtime?

I did not fully understand your issue. Could you please provide small test/program that can reproduce your issue?

Hello, thanks for your reply.

We have 100 entries successfully entered into leveldb.

key1 | value1
key2 | value2
key3 | value3
...
key99 | value99
key100 | value100

When we are removing the entries in the while statement below, 99 values are deleted successfully. However, the first key remains in the database like this:

key1 | "null"

The removal is taking place like this:

DBIterator iterator = db.iterator();

while (iterator.hasNext()) {
Map.Entry<byte[], byte[]> next = iterator.next();
db.delete(next.getKey());
}

Am I iterating incorrectly? Do I need to use iterator.seekToFirst(); to reset the iterator? Or should I use snapshot to iterate? Or should deletes be done as a batch? Perhaps the Options need some changes?

I have tried for 2 days, and cannot successfully remove the final value totally.

This seems like the same issue reported in 2018: #97

Thank you for your help.

I think I have solved this.

If you google LevelDB Java implementation, a very popular tutorial appears with the following iteration code:

while (iterator.hasNext()) {
Map.Entry<byte[], byte[]> next = iterator.next();

However the above works 99.99% of the time. The 0.01% is identified when we are inside a loop and a single entry will remain behind in a corrupted format as described above. This I suspect is because the iterator falls out of sync at the beginning or at the end of the loop.

Your ReadMe instructions on Github correct the issue, by implementing the iteration correctly, by using seekToFirst.

DBIterator iterator = db.iterator();
try {
for(iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {
String key = asString(iterator.peekNext().getKey());
String value = asString(iterator.peekNext().getValue());
System.out.println(key+" = "+value);
}
} finally {
iterator.close();
}

I will test this for a further 24 hours, then close the issue if resolved.