diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryMemTable.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryMemTable.java index f54d73a67cb..840f681be9d 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryMemTable.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/EntryMemTable.java @@ -320,6 +320,9 @@ public long addEntry(long ledgerId, long entryId, final ByteBuffer entry, final try { EntryKeyValue toAdd = cloneWithAllocator(ledgerId, entryId, entry); size = internalAdd(toAdd); + if (size == 0) { + skipListSemaphore.release(len); + } } finally { this.lock.readLock().unlock(); } diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/EntryMemTableTest.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/EntryMemTableTest.java index 946af02325e..f067f11e3e9 100644 --- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/EntryMemTableTest.java +++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/EntryMemTableTest.java @@ -451,5 +451,25 @@ public void run() { assertEquals("listOfEntries should be sorted", Long.valueOf(i + 1), listOfEntries.get(i)); } } + + @Test + public void testAddSameEntries() throws IOException { + final long ledgerId = 1; + final long entryId = 1; + final int size = 10; + final byte[] bytes = new byte[size]; + final int initialPermits = memTable.skipListSemaphore.availablePermits(); + + for (int i = 0; i < 5; i++) { + memTable.addEntry(ledgerId, entryId, ByteBuffer.wrap(bytes), this); + assertEquals(memTable.kvmap.size(), 1); + assertEquals(memTable.skipListSemaphore.availablePermits(), initialPermits - size); + } + + memTable.snapshot(Checkpoint.MAX); + memTable.flush(this); + assertEquals(memTable.kvmap.size(), 0); + assertEquals(memTable.skipListSemaphore.availablePermits(), initialPermits); + } }