Skip to content

Commit 8d038ad

Browse files
committed
Merge branch 'feature/poi-unloading-v0' into ver/1.21.1
2 parents 716d21c + 72c6ecd commit 8d038ad

File tree

7 files changed

+94
-0
lines changed

7 files changed

+94
-0
lines changed

c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/Config.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@ public class Config {
2020
""")
2121
.getBoolean(false, false);
2222

23+
public static final boolean allowPOIUnloading = new ConfigSystem.ConfigAccessor()
24+
.key("chunkSystem.allowPOIUnloading")
25+
.comment("""
26+
Whether to allow POIs (Point of Interest) to be unloaded
27+
Unloaded POIs are reloaded on-demand or when the corresponding chunks are loaded again,
28+
which should not cause any behavior change
29+
\s
30+
Note:
31+
Vanilla never unloads POIs when chunks unload, causing small memory leaks
32+
These leaks adds up and eventually cause issues after generating millions of chunks
33+
in a single world instance
34+
""")
35+
.getBoolean(true, false);
36+
2337
public static void init() {
2438
// intentionally empty
2539
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.ishland.c2me.rewrites.chunksystem.common.ducks;
2+
3+
import net.minecraft.util.math.ChunkPos;
4+
5+
public interface IPOIUnloading {
6+
7+
void c2me$unloadPoi(ChunkPos pos);
8+
9+
default boolean c2me$shouldUnloadPoi(ChunkPos pos) {
10+
return false;
11+
}
12+
13+
}

c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/statuses/ReadFromDisk.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.ishland.c2me.rewrites.chunksystem.common.ChunkState;
1111
import com.ishland.c2me.rewrites.chunksystem.common.Config;
1212
import com.ishland.c2me.rewrites.chunksystem.common.NewChunkStatus;
13+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.IPOIUnloading;
1314
import com.ishland.c2me.rewrites.chunksystem.common.fapi.LifecycleEventInvoker;
1415
import com.ishland.flowsched.scheduler.ItemHolder;
1516
import com.ishland.flowsched.scheduler.KeyStatusPair;
@@ -142,6 +143,8 @@ public CompletionStage<Void> downgradeFromThis(ChunkLoadingContext context) {
142143
listener.setChunkStatus(context.holder().getKey(), null);
143144
}
144145

146+
((IPOIUnloading) ((IThreadedAnvilChunkStorage) context.tacs()).getPointOfInterestStorage()).c2me$unloadPoi(context.holder().getKey());
147+
145148
context.holder().getItem().set(new ChunkState(null, null, null));
146149
}, ((IThreadedAnvilChunkStorage) context.tacs()).getMainThreadExecutor());
147150
}

c2me-rewrites-chunk-system/src/main/java/com/ishland/c2me/rewrites/chunksystem/common/statuses/ReadFromDiskAsync.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.ishland.c2me.rewrites.chunksystem.common.async_chunkio.ChunkIoMainThreadTaskUtils;
1919
import com.ishland.c2me.rewrites.chunksystem.common.async_chunkio.ProtoChunkExtension;
2020
import com.ishland.c2me.rewrites.chunksystem.common.async_chunkio.SerializingRegionBasedStorageExtension;
21+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.IPOIUnloading;
2122
import com.ishland.c2me.rewrites.chunksystem.common.fapi.LifecycleEventInvoker;
2223
import com.ishland.flowsched.scheduler.ItemHolder;
2324
import com.ishland.flowsched.scheduler.KeyStatusPair;
@@ -167,6 +168,8 @@ public CompletionStage<Void> downgradeFromThis(ChunkLoadingContext context) {
167168
((IThreadedAnvilChunkStorage) context.tacs()).getWorldGenerationProgressListener().setChunkStatus(chunk.getPos(), null);
168169
((IThreadedAnvilChunkStorage) context.tacs()).getChunkToNextSaveTimeMs().remove(chunk.getPos().toLong());
169170

171+
((IPOIUnloading) ((IThreadedAnvilChunkStorage) context.tacs()).getPointOfInterestStorage()).c2me$unloadPoi(context.holder().getKey());
172+
170173
context.holder().getItem().set(new ChunkState(null, null, null));
171174
}, ((IThreadedAnvilChunkStorage) context.tacs()).getMainThreadExecutor());
172175
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.ishland.c2me.rewrites.chunksystem.mixin;
2+
3+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.IPOIUnloading;
4+
import it.unimi.dsi.fastutil.longs.LongSet;
5+
import net.minecraft.util.math.ChunkPos;
6+
import net.minecraft.world.poi.PointOfInterestStorage;
7+
import org.spongepowered.asm.mixin.Final;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Shadow;
10+
11+
@Mixin(PointOfInterestStorage.class)
12+
public abstract class MixinPointOfInterestStorage implements IPOIUnloading {
13+
14+
@Shadow @Final private LongSet preloadedChunks;
15+
16+
@Override
17+
public boolean c2me$shouldUnloadPoi(ChunkPos pos) {
18+
return !this.preloadedChunks.contains(pos.toLong());
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.ishland.c2me.rewrites.chunksystem.mixin;
2+
3+
import com.ishland.c2me.rewrites.chunksystem.common.Config;
4+
import com.ishland.c2me.rewrites.chunksystem.common.ducks.IPOIUnloading;
5+
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
6+
import net.minecraft.util.math.ChunkPos;
7+
import net.minecraft.util.math.ChunkSectionPos;
8+
import net.minecraft.world.HeightLimitView;
9+
import net.minecraft.world.storage.SerializingRegionBasedStorage;
10+
import org.spongepowered.asm.mixin.Final;
11+
import org.spongepowered.asm.mixin.Mixin;
12+
import org.spongepowered.asm.mixin.Shadow;
13+
14+
import java.util.Optional;
15+
16+
@Mixin(SerializingRegionBasedStorage.class)
17+
public abstract class MixinSerializingRegionBasedStorage<R> implements IPOIUnloading {
18+
19+
@Shadow protected abstract void save(ChunkPos pos);
20+
21+
@Shadow @Final protected HeightLimitView world;
22+
23+
@Shadow @Final private Long2ObjectMap<Optional<R>> loadedElements;
24+
25+
@Override
26+
public void c2me$unloadPoi(ChunkPos pos) {
27+
if (!Config.allowPOIUnloading) return;
28+
29+
if (!this.c2me$shouldUnloadPoi(pos)) {
30+
return;
31+
}
32+
33+
this.save(pos);
34+
for (int i = this.world.getBottomSectionCoord(); i < this.world.getTopSectionCoord(); i++) {
35+
this.loadedElements.remove(ChunkSectionPos.asLong(pos.x, i, pos.z));
36+
}
37+
}
38+
39+
}

c2me-rewrites-chunk-system/src/main/resources/c2me-rewrites-chunk-system.mixins.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"MixinChunkTicketManagerTicketDistanceLevelPropagator",
1111
"MixinMinecraftServer",
1212
"MixinNoiseChunkGenerator",
13+
"MixinPointOfInterestStorage",
14+
"MixinSerializingRegionBasedStorage",
1315
"MixinServerChunkManager",
1416
"MixinThreadedAnvilChunkStorage",
1517
"async_serialization.MixinBlender",

0 commit comments

Comments
 (0)