Skip to content

Commit

Permalink
Merge pull request #1299 from chrisdennis/issue-1291
Browse files Browse the repository at this point in the history
Fixes #1291 : Ensure single element chains are moved correctly during compaction
  • Loading branch information
cljohnso committed Jul 8, 2016
2 parents 33fa91f + 2b29dcd commit f299e3f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
Expand Up @@ -53,8 +53,12 @@ public OffHeapChainMap(PageSource source, Portability<? super K> keyPortability,
public void evicting(Callable<Map.Entry<K, InternalChain>> callable) {
try {
Map.Entry<K, InternalChain> entry = callable.call();
if (evictionListener != null) {
evictionListener.onEviction(entry.getKey());
try {
if (evictionListener != null) {
evictionListener.onEviction(entry.getKey());
}
} finally {
entry.getValue().close();
}
} catch (Exception e) {
throw new AssertionError(e);
Expand Down
Expand Up @@ -538,6 +538,10 @@ public boolean moved(long from, long to) {
return false;
} else {
long tail = storage.readLong(to + CHAIN_HEADER_TAIL_OFFSET);
if (tail == from + CHAIN_HEADER_SIZE) {
tail = to + CHAIN_HEADER_SIZE;
storage.writeLong(to + CHAIN_HEADER_TAIL_OFFSET, tail);
}
storage.writeLong(tail + ELEMENT_HEADER_NEXT_OFFSET, to);
for (AttachedInternalChain activeChain : activeChains) {
activeChain.moved(from, to);
Expand Down
Expand Up @@ -16,6 +16,7 @@
package org.ehcache.clustered.server.offheap;

import java.nio.ByteBuffer;
import java.util.Random;

import org.ehcache.clustered.common.internal.store.Chain;
import org.ehcache.clustered.common.internal.store.Element;
Expand All @@ -30,6 +31,7 @@
import org.terracotta.offheapstore.buffersource.OffHeapBufferSource;
import org.terracotta.offheapstore.exceptions.OversizeMappingException;
import org.terracotta.offheapstore.paging.UnlimitedPageSource;
import org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
Expand All @@ -39,6 +41,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.terracotta.offheapstore.util.MemoryUnit.MEGABYTES;

public class OffHeapServerStoreTest extends ServerStoreTest {

Expand Down Expand Up @@ -161,4 +164,33 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
assertThat(payload.remaining(), is(8));
}

@Test
public void testCrossSegmentShrinking() {
long seed = System.nanoTime();
Random random = new Random(seed);
try {
OffHeapServerStore store = new OffHeapServerStore(new UpfrontAllocatingPageSource(new OffHeapBufferSource(), MEGABYTES.toBytes(1L), MEGABYTES.toBytes(1)), 16);

ByteBuffer smallValue = ByteBuffer.allocate(1024);
for (int i = 0; i < 10000; i++) {
try {
store.getAndAppend(random.nextInt(500), smallValue.duplicate());
} catch (OversizeMappingException e) {
//ignore
}
}

ByteBuffer largeValue = ByteBuffer.allocate(100 * 1024);
for (int i = 0; i < 10000; i++) {
try {
store.getAndAppend(random.nextInt(500), largeValue.duplicate());
} catch (OversizeMappingException e) {
//ignore
}
}
} catch (Throwable t) {
throw (AssertionError) new AssertionError("Failed with seed " + seed).initCause(t);
}
}

}

0 comments on commit f299e3f

Please sign in to comment.