diff --git a/src/one/nio/mem/MappedFile.java b/src/one/nio/mem/MappedFile.java index 553e0fcf..1c3328b6 100755 --- a/src/one/nio/mem/MappedFile.java +++ b/src/one/nio/mem/MappedFile.java @@ -160,9 +160,17 @@ public static long map(RandomAccessFile f, int mode, long start, long size) thro } try { - Method map0 = Class.forName("sun.nio.ch.FileChannelImpl").getDeclaredMethod("map0", int.class, long.class, long.class); - map0.setAccessible(true); - return (Long) map0.invoke(f.getChannel(), mode, start, size); + Class cls = Class.forName("sun.nio.ch.FileChannelImpl"); + Method map0 = JavaInternals.getMethod(cls, "map0", int.class, long.class, long.class); + if (map0 != null) { + return (long) map0.invoke(f.getChannel(), mode, start, size); + } + // Newer JDK has an extra 'sync' argument + map0 = JavaInternals.getMethod(cls, "map0", int.class, long.class, long.class, boolean.class); + if (map0 != null) { + return (long) map0.invoke(f.getChannel(), mode, start, size, false); + } + throw new IllegalStateException("map0 method not found"); } catch (InvocationTargetException e) { Throwable target = e.getTargetException(); throw (target instanceof IOException) ? (IOException) target : new IOException(target); @@ -179,8 +187,11 @@ public static void unmap(long start, long size) { } try { - Method unmap0 = Class.forName("sun.nio.ch.FileChannelImpl").getDeclaredMethod("unmap0", long.class, long.class); - unmap0.setAccessible(true); + Class cls = Class.forName("sun.nio.ch.FileChannelImpl"); + Method unmap0 = JavaInternals.getMethod(cls, "unmap0", long.class, long.class); + if (unmap0 == null) { + throw new IllegalStateException("unmap0 method not found"); + } unmap0.invoke(null, start, size); } catch (ReflectiveOperationException e) { throw new IllegalStateException(e); diff --git a/src/one/nio/mem/OffheapMap.java b/src/one/nio/mem/OffheapMap.java index 4d80d50a..8727fddd 100755 --- a/src/one/nio/mem/OffheapMap.java +++ b/src/one/nio/mem/OffheapMap.java @@ -431,20 +431,24 @@ public void clear() { } public void iterate(Visitor visitor) { - iterate(visitor, 0, 1); + iterate(visitor, 0, capacity, 1); } public void iterate(final Visitor visitor, final int workers) { AsyncExecutor.fork(workers, new ParallelTask() { @Override public void execute(int taskNum, int taskCount) { - iterate(visitor, taskNum, taskCount); + iterate(visitor, taskNum, capacity, taskCount); } }); } - public void iterate(Visitor visitor, int taskNum, int taskCount) { - for (int i = taskNum; i < capacity; i += taskCount) { + public void iterate(Visitor visitor, int start, int end, int step) { + if (start < 0 || end > capacity) { + throw new IndexOutOfBoundsException(); + } + + for (int i = start; i < end; i += step) { long currentPtr = mapBase + (long) i * 8; RWLock lock = locks[i & (CONCURRENCY_LEVEL - 1)].lockRead(); try { @@ -458,20 +462,24 @@ public void iterate(Visitor visitor, int taskNum, int taskCount) { } public void iterate(WritableVisitor visitor) { - iterate(visitor, 0, 1); + iterate(visitor, 0, capacity, 1); } public void iterate(final WritableVisitor visitor, final int workers) { AsyncExecutor.fork(workers, new ParallelTask() { @Override public void execute(int taskNum, int taskCount) { - iterate(visitor, taskNum, taskCount); + iterate(visitor, taskNum, capacity, taskCount); } }); } - public void iterate(WritableVisitor visitor, int taskNum, int taskCount) { - for (int i = taskNum; i < capacity; i += taskCount) { + public void iterate(WritableVisitor visitor, int start, int end, int step) { + if (start < 0 || end > capacity) { + throw new IndexOutOfBoundsException(); + } + + for (int i = start; i < end; i += step) { long currentPtr = mapBase + (long) i * 8; RWLock lock = locks[i & (CONCURRENCY_LEVEL - 1)].lockWrite(); try { @@ -543,7 +551,7 @@ public static class Record { protected final RWLock lock; protected long entry; - protected Record(OffheapMap map, RWLock lock, long entry) { + public Record(OffheapMap map, RWLock lock, long entry) { this.map = map; this.lock = lock; this.entry = entry; @@ -591,7 +599,7 @@ public static class WritableRecord extends Record { protected K key; protected long currentPtr; - protected WritableRecord(OffheapMap map, RWLock lock, long entry, K key, long currentPtr) { + public WritableRecord(OffheapMap map, RWLock lock, long entry, K key, long currentPtr) { super(map, lock, entry); this.key = key; this.currentPtr = currentPtr; diff --git a/src/one/nio/mem/SharedMemoryFixedMap.java b/src/one/nio/mem/SharedMemoryFixedMap.java index 88f26532..23d28728 100755 --- a/src/one/nio/mem/SharedMemoryFixedMap.java +++ b/src/one/nio/mem/SharedMemoryFixedMap.java @@ -35,7 +35,7 @@ protected SharedMemoryFixedMap(String fileName, long fileSize, int valueSize, lo this.allocator = createFixedSizeAllocator(getEntrySize(valueSize)); } - private static int getEntrySize(int valueSize) { + protected static int getEntrySize(int valueSize) { return (valueSize + (HEADER_SIZE + 7)) & ~7; // align to 8-byte boundary }