--- a/net/minecraft/world/level/lighting/DataLayerStorageMap.java
+++ b/net/minecraft/world/level/lighting/DataLayerStorageMap.java
@@ -9,10 +9,23 @@
     private final long[] lastSectionKeys = new long[2];
     private final DataLayer[] lastSections = new DataLayer[2];
     private boolean cacheEnabled;
-    protected final Long2ObjectOpenHashMap<DataLayer> map;
+    protected final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> data; // Paper - avoid copying light data
+    protected final boolean isVisible; // Paper - avoid copying light data
+    java.util.function.Function<Long, DataLayer> lookup; // Paper - faster branchless lookup
 
-    protected DataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays) {
-        this.map = arrays;
+    // Paper start - avoid copying light data
+    protected DataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> data, boolean isVisible) {
+        if (isVisible) {
+            data.performUpdatesLockMap();
+        }
+        this.data = data;
+        this.isVisible = isVisible;
+        if (isVisible) {
+            lookup = data::getVisibleAsync;
+        } else {
+            lookup = data::getUpdating;
+        }
+        // Paper end - avoid copying light data
         this.clearCache();
         this.cacheEnabled = true;
     }
@@ -20,16 +33,17 @@
     public abstract M copy();
 
     public void copyDataLayer(long pos) {
-        this.map.put(pos, this.map.get(pos).copy());
+        if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
+        this.data.queueUpdate(pos, ((DataLayer) this.data.getUpdating(pos)).copy()); // Paper - avoid copying light data
         this.clearCache();
     }
 
     public boolean hasLayer(long chunkPos) {
-        return this.map.containsKey(chunkPos);
+        return lookup.apply(chunkPos) != null; // Paper - avoid copying light data
     }
 
     @Nullable
-    public DataLayer getLayer(long chunkPos) {
+    public final DataLayer getLayer(long chunkPos) { // Paper - final
         if (this.cacheEnabled) {
             for(int i = 0; i < 2; ++i) {
                 if (chunkPos == this.lastSectionKeys[i]) {
@@ -38,7 +52,7 @@
             }
         }
 
-        DataLayer dataLayer = this.map.get(chunkPos);
+        DataLayer dataLayer = lookup.apply(chunkPos); // Paper - avoid copying light data
         if (dataLayer == null) {
             return null;
         } else {
@@ -58,11 +72,13 @@
 
     @Nullable
     public DataLayer removeLayer(long chunkPos) {
-        return this.map.remove(chunkPos);
+        if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
+        return (DataLayer) this.data.queueRemove(chunkPos); // Paper - avoid copying light data
     }
 
     public void setLayer(long pos, DataLayer data) {
-        this.map.put(pos, data);
+        if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
+        this.data.queueUpdate(pos, data); // Paper - avoid copying light data
     }
 
     public void clearCache() {
