From f87af8ad78c39479cbc649e556ba271cb2feb2e7 Mon Sep 17 00:00:00 2001 From: Ivan Rakov Date: Fri, 4 Jun 2021 17:35:31 +0300 Subject: [PATCH] Completely file disable locking if property is set, closes https://github.com/OpenHFT/Chronicle-Map/issues/276 --- .../chronicle/map/ChronicleMapBuilder.java | 41 ++++--------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index a9271dca2..e7db35b4e 100644 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -54,7 +54,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -480,32 +479,6 @@ public final class ChronicleMapBuilder implements return (long) v; } - /** - * When Chronicle Maps are created using {@link #createPersistedTo(File)} or - * {@link #recoverPersistedTo(File, boolean)} or {@link - * #createOrRecoverPersistedTo(File, boolean)} methods, file lock on the Chronicle Map's file is - * acquired, that shouldn't be done from concurrent threads within the same JVM process. So - * creation of Chronicle Maps persisted to the same File should be synchronized across JVM's - * threads. Simple way would be to synchronize on some static (lock) object, but would serialize - * all Chronicle Maps creations (persisted to any files), ConcurrentHashMap#compute() gives more - * scalability. ConcurrentHashMap is used effectively for lock striping only, because the - * entries are not even landing the map, because compute() always returns null. - */ - private static void fileLockedIO(@NotNull final File file, - @NotNull final FileChannel fileChannel, - @NotNull final FileIOAction fileIOAction) { - FILE_LOCKING_CONTROL.compute(file, (k, v) -> { - try { - try (FileLock ignored = fileChannel.lock()) { - fileIOAction.fileIOAction(); - } - return null; - } catch (IOException e) { - throw Jvm.rethrow(e); - } - }); - } - private boolean isKeySizeKnown() { return keyBuilder.sizeIsStaticallyKnown; } @@ -1722,7 +1695,9 @@ public final class ChronicleMapBuilder implements final AtomicBoolean newFile = new AtomicBoolean(); final FileChannel fileChannel = raf.getChannel(); - fileLockedIO(canonicalFile, fileChannel, () -> { + FileLockUtil.acquireExclusiveFileLock(canonicalFile, fileChannel); + + try { if (raf.length() == 0) { map.set(newMap()); headerBuffer.set(writeHeader(fileChannel, map.get())); @@ -1730,7 +1705,10 @@ public final class ChronicleMapBuilder implements } else { newFile.set(false); } - }); + } + finally { + FileLockUtil.releaseFileLock(canonicalFile); + } if (newFile.get()) { final int headerSize = headerBuffer.get().remaining(); @@ -2026,11 +2004,6 @@ public final class ChronicleMapBuilder implements private enum ChecksumEntries {YES, NO, IF_PERSISTED} - @FunctionalInterface - private interface FileIOAction { - void fileIOAction() throws IOException; - } - private static final class EntrySizeInfo { private final double averageEntrySize; private final int worstAlignment;