mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-11-01 08:50:06 +00:00
Fixed lattice eviction race
- Lattice eviction sorts a snapshot of tile access stamps - Concurrent tile use during eviction no longer breaks the sort - Test covers eviction under concurrent fills
This commit is contained in:
1 parent
6ceda7c53b
commit
618bb28591
2 files changed
+44
-10
No files matched your search
@@ -138,19 +138,19 @@ public final class HeightLattice {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
List<Map.Entry<Long, Tile>> idle = new ArrayList<>(tiles.size());
|
List<IdleTile> idle = new ArrayList<>(tiles.size());
|
||||||
for (Map.Entry<Long, Tile> entry : tiles.entrySet()) {
|
for (Map.Entry<Long, Tile> entry : tiles.entrySet()) {
|
||||||
if (entry.getValue().pending.get() == 0) {
|
|
||||||
idle.add(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idle.sort(Comparator.comparingLong(entry -> entry.getValue().used));
|
|
||||||
int target = capacityTiles - (capacityTiles >> 3);
|
|
||||||
for (int index = 0; index < idle.size() && tiles.size() > target; index++) {
|
|
||||||
Map.Entry<Long, Tile> entry = idle.get(index);
|
|
||||||
Tile tile = entry.getValue();
|
Tile tile = entry.getValue();
|
||||||
if (tile.pending.get() == 0) {
|
if (tile.pending.get() == 0) {
|
||||||
tiles.remove(entry.getKey(), tile);
|
idle.add(new IdleTile(entry.getKey(), tile, tile.used));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idle.sort(Comparator.comparingLong(IdleTile::used));
|
||||||
|
int target = capacityTiles - (capacityTiles >> 3);
|
||||||
|
for (int index = 0; index < idle.size() && tiles.size() > target; index++) {
|
||||||
|
IdleTile candidate = idle.get(index);
|
||||||
|
if (candidate.tile().pending.get() == 0) {
|
||||||
|
tiles.remove(candidate.key(), candidate.tile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -386,6 +386,9 @@ public final class HeightLattice {
|
|||||||
int cellZ(int index);
|
int cellZ(int index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record IdleTile(Long key, Tile tile, long used) {
|
||||||
|
}
|
||||||
|
|
||||||
private record Span(int cellX0, int cellZ0, int width, int stride) implements Nodes {
|
private record Span(int cellX0, int cellZ0, int width, int stride) implements Nodes {
|
||||||
@Override
|
@Override
|
||||||
public int cellX(int index) {
|
public int cellX(int index) {
|
||||||
|
|||||||
@@ -100,6 +100,37 @@ public class HeightLatticeTest {
|
|||||||
assertEquals(DISTINCT_ACROSS_NINE, source.samples());
|
assertEquals(DISTINCT_ACROSS_NINE, source.samples());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void evictionToleratesConcurrentTileUse() throws Exception {
|
||||||
|
HeightLattice lattice = new HeightLattice(new CountingSource(), 1, false, 96 * 1024);
|
||||||
|
int threads = 12;
|
||||||
|
CyclicBarrier start = new CyclicBarrier(threads);
|
||||||
|
ExecutorService pool = Executors.newFixedThreadPool(threads);
|
||||||
|
try {
|
||||||
|
List<Future<Void>> results = new ArrayList<>();
|
||||||
|
for (int thread = 0; thread < threads; thread++) {
|
||||||
|
long seed = 31L * thread + 7L;
|
||||||
|
Callable<Void> task = () -> {
|
||||||
|
Random random = new Random(seed);
|
||||||
|
HydrologySampleBuffer out = new HydrologySampleBuffer(4);
|
||||||
|
start.await();
|
||||||
|
for (int fill = 0; fill < 40_000; fill++) {
|
||||||
|
int tileX = random.nextInt(24);
|
||||||
|
int tileZ = random.nextInt(24);
|
||||||
|
lattice.fill(tileX * 32 + random.nextInt(31), tileZ * 32 + random.nextInt(31), 2, 2, out);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
results.add(pool.submit(task));
|
||||||
|
}
|
||||||
|
for (Future<Void> result : results) {
|
||||||
|
result.get(120, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
pool.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void returnsBitIdenticalValues() {
|
public void returnsBitIdenticalValues() {
|
||||||
HeightLattice full = new HeightLattice(new CountingSource(), 8, false, 1 << 16);
|
HeightLattice full = new HeightLattice(new CountingSource(), 8, false, 1 << 16);
|
||||||
|
|||||||
Reference in new issue
Block a user