Skip to content

Commit

Permalink
Merge branch 'master' into rxsocks
Browse files Browse the repository at this point in the history
  • Loading branch information
RockyLOMO committed Dec 7, 2024
2 parents 87c12ca + 4436af0 commit 71c6936
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
29 changes: 16 additions & 13 deletions rxlib/src/main/java/org/rx/io/CompositeLock.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,29 @@ enum Flags implements NEnum<Flags> {

private final FileStream owner;
private final FlagsEnum<Flags> flags;
final Map<FileStream.Block, ReadWriteLock> rwLocks = Collections.synchronizedMap(new ReferenceMap<>(AbstractReferenceMap.ReferenceStrength.HARD, AbstractReferenceMap.ReferenceStrength.WEAK));
final Map<FileStream.Block, ReadWriteLock> rwLocks = new ReferenceMap<>(AbstractReferenceMap.ReferenceStrength.HARD, AbstractReferenceMap.ReferenceStrength.WEAK);

@SneakyThrows
private <T> T lock(FileStream.Block block, boolean shared, @NonNull Func<T> fn) {
Lock lock = null;
if (flags.has(Flags.READ_WRITE_LOCK)) {
ReadWriteLock rwLock = rwLocks.computeIfAbsent(block, k -> {
ReadWriteLock t = overlaps(k.position, k.size);
if (t == null) {
t = new ReentrantReadWriteLock();
FileLock fLock = null;
try {
if (flags.has(Flags.READ_WRITE_LOCK)) {
ReadWriteLock rwLock;
synchronized (rwLocks) {
rwLock = rwLocks.computeIfAbsent(block, k -> {
ReadWriteLock t = overlaps(k.position, k.size);
if (t == null) {
t = new ReentrantReadWriteLock();
}
return t;
});
}
return t;
});
// log.info("Lock {} - {}", rwLock, block);
lock = shared ? rwLock.readLock() : rwLock.writeLock();
lock.lock();
}
lock = shared ? rwLock.readLock() : rwLock.writeLock();
lock.lock();
}

FileLock fLock = null;
try {
if (flags.has(Flags.FILE_LOCK)) {
fLock = owner.getRandomAccessFile().getChannel().lock(block.position, block.size, shared);
}
Expand Down
31 changes: 31 additions & 0 deletions rxlib/src/test/java/org/rx/io/TestIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.AbstractReferenceMap;
import org.apache.commons.collections4.map.ReferenceMap;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -34,6 +36,8 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import static org.rx.core.Extends.sleep;
import static org.rx.core.Sys.toJsonString;
Expand Down Expand Up @@ -461,6 +465,33 @@ public void kvsIdx() {
}, 100);
log.info("{}", indexer);
}

final Map<FileStream.Block, ReadWriteLock> rwLocks = Collections.synchronizedMap(new ReferenceMap<>(AbstractReferenceMap.ReferenceStrength.HARD, AbstractReferenceMap.ReferenceStrength.WEAK));

@Test
public void overlapsLock() {
ReentrantReadWriteLock r = new ReentrantReadWriteLock();
rwLocks.put(new FileStream.Block(4, 2), r);
assert overlaps(0, 4) == null;
assert overlaps(6, 10) == null;
assert overlaps(3, 1) == null;
assert overlaps(3, 2) == r;
assert overlaps(3, 4) == r;
assert overlaps(5, 1) == r;
assert overlaps(5, 3) == r;
}

private ReadWriteLock overlaps(long position, long size) {
for (Map.Entry<FileStream.Block, ReadWriteLock> entry : rwLocks.entrySet()) {
FileStream.Block block = entry.getKey();
if (position + size <= block.position)
continue; // That is below this
if (block.position + block.size <= position)
continue; // This is below that
return entry.getValue();
}
return null;
}
//endregion

@Test
Expand Down

0 comments on commit 71c6936

Please sign in to comment.