dain / leveldb

Port of LevelDB to Java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Background compaction produces invalid file size

zb3 opened this issue · comments

commented

First of all note that I don't really know how LevelDB works internally, I just tried to find out what was causing cpp version of leveldb to be unable to load databases saved by this version...

So in DbImpl.java file, around line 1171 we have:

        long currentEntries = compactionState.builder.getEntryCount();
        compactionState.builder.finish();

        long currentBytes = compactionState.builder.getFileSize();
        compactionState.currentFileSize = currentBytes;

The problem is that getFileSize() in this case returns file size + 4.
That function is:

        return position + dataBlockBuilder.currentSizeEstimate();

But in this case we've already called finish and the footer was already written.
finish() called flush() which reset dataBlockBuilder.
For empty BlockBuilder, currentSizeEstimate returns SIZE_OF_INT (4), but in this case it shouldn't even be called because the file was already finished

A quick but ugly fix I made was to change:

        long currentBytes = compactionState.builder.getFileSize();

to

        long currentBytes = compactionState.builder.getFileSize()-SIZE_OF_INT;

And now background compaction seems to work.