mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
* added AbstractClosable * added Jvm.init() * added disable.thread.safety * ignore thread safety check * disabled threadSafetyCheck for chronicle map * removed init() * changed isOpen() to be !isClosed() * throwExceptionIfClosed() now creates a new ChronicleHashClosedException() * added test testRemainingAutoResizesAfterClose Co-authored-by: Rob Austin <rob.austin@boundedbuffer.co.uk>
This commit is contained in:
@@ -16,10 +16,12 @@
|
||||
|
||||
package net.openhft.chronicle.hash;
|
||||
|
||||
import net.openhft.chronicle.core.io.ClosedIllegalStateException;
|
||||
|
||||
/**
|
||||
* Thrown when a {@link ChronicleHash} is accessed after {@link ChronicleHash#close()}.
|
||||
*/
|
||||
public final class ChronicleHashClosedException extends IllegalStateException {
|
||||
public final class ChronicleHashClosedException extends ClosedIllegalStateException {
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
public ChronicleHashClosedException(ChronicleHash hash) {
|
||||
@@ -29,4 +31,8 @@ public final class ChronicleHashClosedException extends IllegalStateException {
|
||||
public ChronicleHashClosedException(String chronicleHashIdentityString) {
|
||||
super("Access to " + chronicleHashIdentityString + " after close()");
|
||||
}
|
||||
|
||||
public ChronicleHashClosedException(String s, Throwable t) {
|
||||
super(s, t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ import net.openhft.chronicle.algo.locks.*;
|
||||
import net.openhft.chronicle.bytes.BytesStore;
|
||||
import net.openhft.chronicle.bytes.MappedBytesStoreFactory;
|
||||
import net.openhft.chronicle.bytes.NativeBytesStore;
|
||||
import net.openhft.chronicle.core.Jvm;
|
||||
import net.openhft.chronicle.core.Maths;
|
||||
import net.openhft.chronicle.core.OS;
|
||||
import net.openhft.chronicle.core.io.AbstractCloseable;
|
||||
import net.openhft.chronicle.core.io.ReferenceOwner;
|
||||
import net.openhft.chronicle.hash.*;
|
||||
import net.openhft.chronicle.hash.impl.util.BuildVersion;
|
||||
@@ -69,7 +71,7 @@ import static net.openhft.chronicle.map.ChronicleHashCorruptionImpl.report;
|
||||
|
||||
public abstract class VanillaChronicleHash<K,
|
||||
C extends HashEntry<K>, SC extends HashSegmentContext<K, ?>,
|
||||
ECQ extends ExternalHashQueryContext<K>>
|
||||
ECQ extends ExternalHashQueryContext<K>> extends AbstractCloseable
|
||||
implements ChronicleHash<K, C, SC, ECQ>, Marshallable {
|
||||
|
||||
public static final long TIER_COUNTERS_AREA_SIZE = 64;
|
||||
@@ -680,7 +682,13 @@ public abstract class VanillaChronicleHash<K,
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() {
|
||||
protected boolean threadSafetyCheck(boolean isUsed) {
|
||||
// disabled for chronicle map
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performClose() {
|
||||
if (resources != null && resources.releaseManually()) {
|
||||
cleanupOnClose();
|
||||
}
|
||||
@@ -698,11 +706,14 @@ public abstract class VanillaChronicleHash<K,
|
||||
keyDataAccess = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return !isClosed()
|
||||
* @Deprecated use !isClosed() instead
|
||||
*/
|
||||
@Deprecated(/*remove in x.23*/)
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
throwExceptionIfClosed();
|
||||
|
||||
return !resources.closed();
|
||||
return !isClosed();
|
||||
}
|
||||
|
||||
public final void checkKey(final Object key) {
|
||||
@@ -715,6 +726,12 @@ public abstract class VanillaChronicleHash<K,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void throwExceptionIfClosed() throws IllegalStateException {
|
||||
if (this.isClosed())
|
||||
throw new ChronicleHashClosedException(this.getClass().getName() + " closed", Jvm.getValue(this, "closedHere"));
|
||||
}
|
||||
|
||||
public final long segmentHeaderAddress(final int segmentIndex) {
|
||||
return bsAddress() + segmentHeadersOffset + ((long) segmentIndex) * segmentHeaderSize;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.core.Jvm;
|
||||
import net.openhft.chronicle.hash.Data;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -27,6 +29,7 @@ import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static net.openhft.chronicle.core.Jvm.*;
|
||||
import static net.openhft.chronicle.hash.Data.bytesEquivalent;
|
||||
import static net.openhft.chronicle.map.BiMapTest.DualLockSuccess.FAIL;
|
||||
import static net.openhft.chronicle.map.BiMapTest.DualLockSuccess.SUCCESS;
|
||||
|
||||
@@ -25,13 +25,14 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import static net.openhft.chronicle.hash.impl.BigSegmentHeader.LOCK_TIMEOUT_SECONDS;
|
||||
import static net.openhft.chronicle.map.ChronicleMap.of;
|
||||
|
||||
public class MapCloseTest {
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@Test
|
||||
public void closeInContextTest() {
|
||||
ChronicleMap<Integer, Integer> map =
|
||||
ChronicleMap.of(Integer.class, Integer.class).entries(1).create();
|
||||
of(Integer.class, Integer.class).entries(1).create();
|
||||
ExternalMapQueryContext<Integer, Integer, ?> cxt = map.queryContext(1);
|
||||
map.close();
|
||||
}
|
||||
@@ -39,7 +40,7 @@ public class MapCloseTest {
|
||||
@Test(expected = ChronicleHashClosedException.class)
|
||||
public void testGetAfterCloseThrowsChronicleHashClosedException() throws InterruptedException {
|
||||
ChronicleMap<Integer, Integer> map =
|
||||
ChronicleMap.of(Integer.class, Integer.class).entries(1).create();
|
||||
of(Integer.class, Integer.class).entries(1).create();
|
||||
Thread t = new Thread(() -> map.close());
|
||||
t.start();
|
||||
t.join();
|
||||
@@ -50,7 +51,7 @@ public class MapCloseTest {
|
||||
public void testIterationAfterCloseThrowsChronicleHashClosedException()
|
||||
throws InterruptedException {
|
||||
ChronicleMap<Integer, Integer> map =
|
||||
ChronicleMap.of(Integer.class, Integer.class).entries(1).create();
|
||||
of(Integer.class, Integer.class).entries(1).create();
|
||||
Thread t = new Thread(() -> map.close());
|
||||
t.start();
|
||||
t.join();
|
||||
@@ -62,18 +63,18 @@ public class MapCloseTest {
|
||||
public void testSizeAfterCloseThrowsChronicleHashClosedException()
|
||||
throws InterruptedException {
|
||||
ChronicleMap<Integer, Integer> map =
|
||||
ChronicleMap.of(Integer.class, Integer.class).entries(1).create();
|
||||
of(Integer.class, Integer.class).entries(1).create();
|
||||
Thread t = new Thread(() -> map.close());
|
||||
t.start();
|
||||
t.join();
|
||||
map.size();
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
@Test
|
||||
public void closeWithContextInAnotherThreadTest() throws InterruptedException {
|
||||
LOCK_TIMEOUT_SECONDS = 2;
|
||||
ChronicleMap<Integer, Integer> map =
|
||||
ChronicleMap.of(Integer.class, Integer.class).entries(1).create();
|
||||
of(Integer.class, Integer.class).entries(1).create();
|
||||
Object lock = new Object();
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
synchronized (lock) {
|
||||
@@ -93,11 +94,19 @@ public class MapCloseTest {
|
||||
LOCK_TIMEOUT_SECONDS = 60;
|
||||
}
|
||||
|
||||
@Test(expected = ChronicleHashClosedException.class)
|
||||
public void testRemainingAutoResizesAfterClose() {
|
||||
ChronicleMap<Integer, Integer> map = of(Integer.class, Integer.class).entries(1).create();
|
||||
map.close();
|
||||
map.remainingAutoResizes();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void vanillaChronicleHashAllContextsExpungeTest() throws InterruptedException {
|
||||
VanillaChronicleMap<Integer, Integer, Void> map =
|
||||
(VanillaChronicleMap<Integer, Integer, Void>)
|
||||
ChronicleMap.of(Integer.class, Integer.class).entries(1).create();
|
||||
of(Integer.class, Integer.class).entries(1).create();
|
||||
Semaphore semaphore = new Semaphore(0);
|
||||
CountDownLatch latch = new CountDownLatch(2);
|
||||
class MapAccessThread extends Thread {
|
||||
|
||||
Reference in New Issue
Block a user