From 162865226460aedff9e62912a81431e708c0d5f0 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 23 Sep 2021 10:44:56 -0400 Subject: [PATCH] BITS BITS EVERYWHERE --- src/main/java/com/volmit/iris/Iris.java | 2 + .../volmit/iris/engine/object/IrisCompat.java | 2 +- .../com/volmit/iris/util/collection/KMap.java | 13 ++ .../com/volmit/iris/util/data/Varint.java | 4 +- .../iris/util/data/palette/BitStorage.java | 2 +- .../CrudeIncrementalIntIdentityHashBiMap.java | 7 - .../util/data/palette/HashMapPalette.java | 49 +++-- .../iris/util/data/palette/LinearPalette.java | 10 +- .../iris/util/data/palette/Palette.java | 2 - .../util/data/palette/PalettedContainer.java | 15 +- .../iris/util/function/Consumer2IO.java | 27 +++ .../volmit/iris/util/hunk/bits/DataBits.java | 191 ++++++++++++++++++ .../iris/util/hunk/bits/DataContainer.java | 146 +++++++++++++ .../iris/util/hunk/bits/HashPalette.java | 74 +++++++ .../iris/util/hunk/bits/LinearPalette.java | 94 +++++++++ .../volmit/iris/util/hunk/bits/Palette.java | 86 ++++++++ .../volmit/iris/util/hunk/bits/Writable.java | 29 +++ .../iris/util/hunk/storage/PaletteHunk.java | 24 ++- .../iris/util/hunk/storage/PaletteOrHunk.java | 18 +- .../util/hunk/view/FunctionalHunkView.java | 2 +- src/main/java/com/volmit/iris/util/io/IO.java | 105 ++++++---- .../com/volmit/iris/util/mantle/Mantle.java | 4 +- .../iris/util/mantle/TectonicPlate.java | 2 +- .../volmit/iris/util/matter/MatterSlice.java | 50 ++--- .../volmit/iris/util/matter/MatterTest.java | 74 +++++++ .../iris/util/matter/slices/RawMatter.java | 2 +- .../com/volmit/iris/util/nbt/mca/MCAFile.java | 6 +- .../com/volmit/iris/util/nbt/mca/MCAUtil.java | 18 +- 28 files changed, 899 insertions(+), 159 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/function/Consumer2IO.java create mode 100644 src/main/java/com/volmit/iris/util/hunk/bits/DataBits.java create mode 100644 src/main/java/com/volmit/iris/util/hunk/bits/DataContainer.java create mode 100644 src/main/java/com/volmit/iris/util/hunk/bits/HashPalette.java create mode 100644 src/main/java/com/volmit/iris/util/hunk/bits/LinearPalette.java create mode 100644 src/main/java/com/volmit/iris/util/hunk/bits/Palette.java create mode 100644 src/main/java/com/volmit/iris/util/hunk/bits/Writable.java create mode 100644 src/main/java/com/volmit/iris/util/matter/MatterTest.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 3a3b91acd..5a8a90dc7 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -45,6 +45,7 @@ import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.io.JarScanner; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.MatterTest; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.IrisService; import com.volmit.iris.util.plugin.Metrics; @@ -447,6 +448,7 @@ public class Iris extends VolmitPlugin implements Listener { J.s(this::setupPapi); J.a(ServerConfigurator::configure, 20); splash(); + J.a(MatterTest::test, 20); if (IrisSettings.get().getStudio().isAutoStartDefaultStudio()) { Iris.info("Starting up auto Studio!"); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisCompat.java b/src/main/java/com/volmit/iris/engine/object/IrisCompat.java index 9e5a19345..089272214 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisCompat.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisCompat.java @@ -53,7 +53,7 @@ public class IrisCompat { try { IO.writeAll(f, defa); } catch (IOException e) { - Iris.error("Failed to write to compat file"); + Iris.error("Failed to writeNodeData to compat file"); Iris.reportError(e); } }); diff --git a/src/main/java/com/volmit/iris/util/collection/KMap.java b/src/main/java/com/volmit/iris/util/collection/KMap.java index e835f4fcd..a46e28e5f 100644 --- a/src/main/java/com/volmit/iris/util/collection/KMap.java +++ b/src/main/java/com/volmit/iris/util/collection/KMap.java @@ -42,6 +42,19 @@ public class KMap extends ConcurrentHashMap { put(gMap); } + public K getKey(V value) + { + for(KeyPair i : keypair()) + { + if(i.getV().equals(value)) + { + return i.getK(); + } + } + + return null; + } + /** * Puts a value into a map-value-list based on the key such that if GMap> where V is GList diff --git a/src/main/java/com/volmit/iris/util/data/Varint.java b/src/main/java/com/volmit/iris/util/data/Varint.java index 8b9aaa6ae..f04b95969 100644 --- a/src/main/java/com/volmit/iris/util/data/Varint.java +++ b/src/main/java/com/volmit/iris/util/data/Varint.java @@ -45,7 +45,7 @@ public final class Varint { * {@link #writeUnsignedVarLong(long, DataOutput)} should be used. * * @param value value to encode - * @param out to write bytes to + * @param out to writeNodeData bytes to * @throws IOException if {@link DataOutput} throws {@link IOException} */ public static void writeSignedVarLong(long value, DataOutput out) throws IOException { @@ -61,7 +61,7 @@ public final class Varint { * instead. This method treats negative input as like a large unsigned value. * * @param value value to encode - * @param out to write bytes to + * @param out to writeNodeData bytes to * @throws IOException if {@link DataOutput} throws {@link IOException} */ public static void writeUnsignedVarLong(long value, DataOutput out) throws IOException { diff --git a/src/main/java/com/volmit/iris/util/data/palette/BitStorage.java b/src/main/java/com/volmit/iris/util/data/palette/BitStorage.java index a60c3322c..a0b664634 100644 --- a/src/main/java/com/volmit/iris/util/data/palette/BitStorage.java +++ b/src/main/java/com/volmit/iris/util/data/palette/BitStorage.java @@ -20,7 +20,6 @@ package com.volmit.iris.util.data.palette; import org.apache.commons.lang3.Validate; -import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLongArray; import java.util.function.IntConsumer; @@ -141,6 +140,7 @@ public class BitStorage { int var2 = cellIndex(var0); long var3 = this.data.get(var2); int var5 = (var0 - var2 * this.valuesPerLong) * this.bits; + this.data.set(var2, var3 & (this.mask << var5 ^ 0xFFFFFFFFFFFFFFFFL) | (var1 & this.mask) << var5); } diff --git a/src/main/java/com/volmit/iris/util/data/palette/CrudeIncrementalIntIdentityHashBiMap.java b/src/main/java/com/volmit/iris/util/data/palette/CrudeIncrementalIntIdentityHashBiMap.java index 78d4af2b5..63dce90cc 100644 --- a/src/main/java/com/volmit/iris/util/data/palette/CrudeIncrementalIntIdentityHashBiMap.java +++ b/src/main/java/com/volmit/iris/util/data/palette/CrudeIncrementalIntIdentityHashBiMap.java @@ -28,19 +28,12 @@ import java.util.concurrent.atomic.AtomicReferenceArray; public class CrudeIncrementalIntIdentityHashBiMap implements IdMap { public static final int NOT_FOUND = -1; - private static final Object EMPTY_SLOT = null; - private static final float LOADFACTOR = 0.8F; - private AtomicReferenceArray keys; - private AtomicIntegerArray values; - private AtomicReferenceArray byId; - private int nextId; - private int size; public CrudeIncrementalIntIdentityHashBiMap(int var0) { diff --git a/src/main/java/com/volmit/iris/util/data/palette/HashMapPalette.java b/src/main/java/com/volmit/iris/util/data/palette/HashMapPalette.java index 066dc2c94..26c1561f4 100644 --- a/src/main/java/com/volmit/iris/util/data/palette/HashMapPalette.java +++ b/src/main/java/com/volmit/iris/util/data/palette/HashMapPalette.java @@ -18,6 +18,8 @@ package com.volmit.iris.util.data.palette; +import com.volmit.iris.Iris; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.nbt.tag.ListTag; @@ -26,38 +28,40 @@ import java.util.function.Function; import java.util.function.Predicate; public class HashMapPalette implements Palette { - private final CrudeIncrementalIntIdentityHashBiMap values; + private final KMap values; private final PaletteResize resizeHandler; private final int bits; + private int id; public HashMapPalette(int var1, PaletteResize var2) { this.bits = var1; this.resizeHandler = var2; - this.values = new CrudeIncrementalIntIdentityHashBiMap<>(1 << var1); + this.values = new KMap<>(); + id = 1; } public int idFor(T var0) { - int var1 = this.values.getId(var0); - if (var1 == -1) { - var1 = this.values.add(var0); - if (var1 >= 1 << this.bits) - { - var1 = this.resizeHandler.onResize(this.bits + 1, var0); - } + if(var0 == null) + { + return 0; } - return var1; - } - public boolean maybeHas(Predicate var0) { - for (int var1 = 0; var1 < getSize(); var1++) { - if (var0.test(this.values.byId(var1))) - return true; - } - return false; + return this.values.computeIfAbsent(var0, (k) -> { + int newId = id++; + + if (newId >= 1 << this.bits) + { + Iris.info(newId + " to..."); + newId = this.resizeHandler.onResize(this.bits + 1, var0); + Iris.info(newId + ".."); + } + + return newId; + }); } public T valueFor(int var0) { - return this.values.byId(var0); + return this.values.getKey(var0); } public int getSize() { @@ -66,16 +70,11 @@ public class HashMapPalette implements Palette { @Override public void read(List data) { - data.forEach(values::add); + data.forEach(this::idFor); } @Override public void write(List toList) { - this.values.iterator().forEachRemaining(i -> { - if(i != null) - { - toList.add(i); - } - }); + toList.addAll(values.keySet()); } } \ No newline at end of file diff --git a/src/main/java/com/volmit/iris/util/data/palette/LinearPalette.java b/src/main/java/com/volmit/iris/util/data/palette/LinearPalette.java index fd327f687..f95bcd113 100644 --- a/src/main/java/com/volmit/iris/util/data/palette/LinearPalette.java +++ b/src/main/java/com/volmit/iris/util/data/palette/LinearPalette.java @@ -56,17 +56,11 @@ public class LinearPalette implements Palette { return resizeHandler.onResize(bits + 1, var0); } - public boolean maybeHas(Predicate var0) { - for (int var1 = 0; var1 < size; var1++) { - if (var0.test(values.get(var1))) - return true; - } - return false; - } - public T valueFor(int var0) { if (var0 >= 0 && var0 < size) + { return this.values.get(var0); + } return null; } diff --git a/src/main/java/com/volmit/iris/util/data/palette/Palette.java b/src/main/java/com/volmit/iris/util/data/palette/Palette.java index 39b50cb60..57c148883 100644 --- a/src/main/java/com/volmit/iris/util/data/palette/Palette.java +++ b/src/main/java/com/volmit/iris/util/data/palette/Palette.java @@ -27,8 +27,6 @@ import java.util.function.Predicate; public interface Palette { int idFor(T paramT); - boolean maybeHas(Predicate paramPredicate); - T valueFor(int paramInt); int getSize(); diff --git a/src/main/java/com/volmit/iris/util/data/palette/PalettedContainer.java b/src/main/java/com/volmit/iris/util/data/palette/PalettedContainer.java index 81d81f4f5..dad5291a0 100644 --- a/src/main/java/com/volmit/iris/util/data/palette/PalettedContainer.java +++ b/src/main/java/com/volmit/iris/util/data/palette/PalettedContainer.java @@ -18,6 +18,8 @@ package com.volmit.iris.util.data.palette; +import com.volmit.iris.Iris; +import com.volmit.iris.util.math.M; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import java.util.List; import java.util.function.Predicate; @@ -64,8 +66,11 @@ public class PalettedContainer implements PaletteResize { for (int var4 = 0; var4 < var2.getSize(); var4++) { T var5 = var3.valueFor(var2.get(var4)); if (var5 != null) + { set(var4, var5); + } } + return this.palette.idFor(var1); } @@ -89,6 +94,12 @@ public class PalettedContainer implements PaletteResize { private void set(int var0, T var1) { int var2 = this.palette.idFor(var1); + + if(M.r(0.003)) + { + Iris.info("ID for " + var1 + " is " + var2 + " Palette: " + palette.getSize()); + } + this.storage.set(var0, var2); } @@ -143,10 +154,6 @@ public class PalettedContainer implements PaletteResize { return var9.getRaw(); } - public boolean maybeHas(Predicate var0) { - return this.palette.maybeHas(var0); - } - public void count(CountConsumer var0) { Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap(); this.storage.getAll(var1 -> int2IntOpenHashMap.put(var1, int2IntOpenHashMap.get(var1) + 1)); diff --git a/src/main/java/com/volmit/iris/util/function/Consumer2IO.java b/src/main/java/com/volmit/iris/util/function/Consumer2IO.java new file mode 100644 index 000000000..678e71464 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/function/Consumer2IO.java @@ -0,0 +1,27 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.function; + +import java.io.IOException; + +@SuppressWarnings({"hiding", "RedundantSuppression"}) +@FunctionalInterface +public interface Consumer2IO { + void accept(A a, B b) throws IOException; +} diff --git a/src/main/java/com/volmit/iris/util/hunk/bits/DataBits.java b/src/main/java/com/volmit/iris/util/hunk/bits/DataBits.java new file mode 100644 index 000000000..52f877657 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/bits/DataBits.java @@ -0,0 +1,191 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.bits; + +import com.volmit.iris.util.data.Varint; +import org.apache.commons.lang3.Validate; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLongArray; +import java.util.function.IntConsumer; + +public class DataBits { + private static final int[] MAGIC = new int[]{ + -1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE, + 0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756, + 0, Integer.MIN_VALUE, 0, 2, 477218588, 477218588, 0, 429496729, 429496729, 0, + 390451572, 390451572, 0, 357913941, 357913941, 0, 330382099, 330382099, 0, 306783378, + 306783378, 0, 286331153, 286331153, 0, Integer.MIN_VALUE, 0, 3, 252645135, 252645135, + 0, 238609294, 238609294, 0, 226050910, 226050910, 0, 214748364, 214748364, 0, + 204522252, 204522252, 0, 195225786, 195225786, 0, 186737708, 186737708, 0, 178956970, + 178956970, 0, 171798691, 171798691, 0, 165191049, 165191049, 0, 159072862, 159072862, + 0, 153391689, 153391689, 0, 148102320, 148102320, 0, 143165576, 143165576, 0, + 138547332, 138547332, 0, Integer.MIN_VALUE, 0, 4, 130150524, 130150524, 0, 126322567, + 126322567, 0, 122713351, 122713351, 0, 119304647, 119304647, 0, 116080197, 116080197, + 0, 113025455, 113025455, 0, 110127366, 110127366, 0, 107374182, 107374182, 0, + 104755299, 104755299, 0, 102261126, 102261126, 0, 99882960, 99882960, 0, 97612893, + 97612893, 0, 95443717, 95443717, 0, 93368854, 93368854, 0, 91382282, 91382282, + 0, 89478485, 89478485, 0, 87652393, 87652393, 0, 85899345, 85899345, 0, + 84215045, 84215045, 0, 82595524, 82595524, 0, 81037118, 81037118, 0, 79536431, + 79536431, 0, 78090314, 78090314, 0, 76695844, 76695844, 0, 75350303, 75350303, + 0, 74051160, 74051160, 0, 72796055, 72796055, 0, 71582788, 71582788, 0, + 70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE, + 0, 5}; + + private final AtomicLongArray data; + private final int bits; + private final long mask; + private final int size; + private final int valuesPerLong; + private final int divideMul; + private final int divideAdd; + private final int divideShift; + + public DataBits(int bits, int length) { + this(bits, length, (AtomicLongArray) null); + } + + public DataBits(int bits, int length, DataInputStream din) throws IOException + { + this(bits, length, longs(din, (length + ((char) (64 / bits)) - 1) / ((char) (64 / bits)))); + } + + public DataBits(int bits, int length, AtomicLongArray data) { + Validate.inclusiveBetween(1L, 32L, bits); + this.size = length; + this.bits = bits; + this.mask = (1L << bits) - 1L; + this.valuesPerLong = (char) (64 / bits); + int var3 = 3 * (valuesPerLong - 1); + this.divideMul = MAGIC[var3]; + this.divideAdd = MAGIC[var3 + 1]; + this.divideShift = MAGIC[var3 + 2]; + int var4 = (length + valuesPerLong - 1) / valuesPerLong; + if (data != null) { + if (data.length() != var4) + { + throw new RuntimeException("NO!"); + } + this.data = data; + } else { + this.data = new AtomicLongArray(var4); + } + } + + private static AtomicLongArray longs(DataInputStream din, int len) throws IOException{ + AtomicLongArray a = new AtomicLongArray(len); + + for(int i = 0; i < len; i++) + { + a.set(i, din.readLong()); + } + + return a; + } + + public DataBits setBits(int newBits) + { + if(bits != newBits) + { + DataBits newData = new DataBits(newBits, size); + AtomicInteger c = new AtomicInteger(0); + getAll((i) -> newData.set(c.incrementAndGet(), i)); + return newData; + } + + return this; + } + + private int cellIndex(int var0) { + long var1 = Integer.toUnsignedLong(this.divideMul); + long var3 = Integer.toUnsignedLong(this.divideAdd); + return (int) (var0 * var1 + var3 >> 32L >> this.divideShift); + } + + @SuppressWarnings("PointlessBitwiseExpression") + public int getAndSet(int var0, int var1) { + Validate.inclusiveBetween(0L, (this.size - 1), var0); + Validate.inclusiveBetween(0L, this.mask, var1); + int var2 = cellIndex(var0); + long var3 = this.data.get(var2); + int var5 = (var0 - var2 * this.valuesPerLong) * this.bits; + int var6 = (int) (var3 >> var5 & this.mask); + this.data.set(var2, var3 & (this.mask << var5 ^ 0xFFFFFFFFFFFFFFFFL) | (var1 & this.mask) << var5); + return var6; + } + + @SuppressWarnings("PointlessBitwiseExpression") + public void set(int var0, int var1) { + Validate.inclusiveBetween(0L, (this.size - 1), var0); + Validate.inclusiveBetween(0L, this.mask, var1); + int var2 = cellIndex(var0); + long var3 = this.data.get(var2); + int var5 = (var0 - var2 * this.valuesPerLong) * this.bits; + + this.data.set(var2, var3 & (this.mask << var5 ^ 0xFFFFFFFFFFFFFFFFL) | (var1 & this.mask) << var5); + } + + public int get(int var0) { + Validate.inclusiveBetween(0L, (size - 1), var0); + int var1 = cellIndex(var0); + long var2 = this.data.get(var1); + int var4 = (var0 - var1 * valuesPerLong) * this.bits; + return (int) (var2 >> var4 & mask); + } + + public AtomicLongArray getRaw() { + return data; + } + + public int getSize() { + return size; + } + + public int getBits() { + return bits; + } + + public void getAll(IntConsumer var0) { + int var1 = 0; + for(int i = 0; i < data.length(); i++) + { + long var5 = data.get(i); + for (int var7 = 0; var7 < valuesPerLong; var7++) { + var0.accept((int) (var5 & mask)); + var5 >>= bits; + if (++var1 >= size) + { + return; + } + } + } + } + + public void write(DataOutputStream dos) throws IOException { + dos.writeByte(bits); + + for(int i = 0; i < data.length(); i++) + { + dos.writeLong(data.get(i)); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/hunk/bits/DataContainer.java b/src/main/java/com/volmit/iris/util/hunk/bits/DataContainer.java new file mode 100644 index 000000000..a515fda80 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/bits/DataContainer.java @@ -0,0 +1,146 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.bits; + +import com.volmit.iris.util.data.Varint; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +public class DataContainer { + protected static final int INITIAL_BITS = 3; + protected static final int LINEAR_BITS_LIMIT = 5; + protected static final int LINEAR_INITIAL_LENGTH = (int) Math.pow(2, LINEAR_BITS_LIMIT) + 1; + protected static final int[] BIT = computeBitLimits(); + private final AtomicReference> palette; + private final AtomicReference data; + private final AtomicInteger bits; + private final int length; + private final Writable writer; + + public DataContainer(Writable writer, int length) + { + this.writer = writer; + this.length = length; + this.palette = new AtomicReference<>(newPalette(INITIAL_BITS)); + this.data = new AtomicReference<>(new DataBits(INITIAL_BITS, length)); + this.bits = new AtomicInteger(INITIAL_BITS); + } + + public byte[] write() throws IOException + { + ByteArrayOutputStream boas = new ByteArrayOutputStream(); + write(boas); + return boas.toByteArray(); + } + + public static DataContainer read(InputStream in, Writable writer) throws IOException { + DataInputStream din = new DataInputStream(in); + return readDin(din, writer); + } + + public static DataContainer readDin(DataInputStream in, Writable writer) throws IOException { + DataInputStream din = new DataInputStream(in); + DataContainer container = new DataContainer<>(writer, Varint.readUnsignedVarInt(din)); + int paletteSize = Varint.readUnsignedVarInt(din); + container.palette.set(container.newPalette(BIT[paletteSize]).from(paletteSize, writer, din)); + container.data.set(new DataBits(container.palette.get().bits(), container.length, din)); + return container; + } + + public void write(OutputStream out) throws IOException + { + DataOutputStream dos = new DataOutputStream(out); + writeDos(dos); + } + + public void writeDos(DataOutputStream out) throws IOException + { + DataOutputStream dos = new DataOutputStream(out); + Varint.writeUnsignedVarInt(length); + Varint.writeUnsignedVarInt(palette.get().size()); + palette.get().iterateIO((data, __) -> writer.writeNodeData(dos, data)); + data.get().write(dos); + } + + private Palette newPalette(int bits) + { + if(bits <= LINEAR_BITS_LIMIT) + { + return new LinearPalette<>(LINEAR_INITIAL_LENGTH); + } + + return new HashPalette<>(); + } + + public void set(int position, T t) + { + int id = palette.get().id(t); + + if(id == -1) + { + id = palette.get().add(t); + } + + data.get().set(position, id); + } + + public T get(int position) + { + int id = data.get().get(position); + + if(id <= 0) + { + return null; + } + + return palette.get().get(id - 1); + } + + public void setBits(int bits) + { + if(this.bits.get() != bits) + { + if(this.bits.get() <= LINEAR_BITS_LIMIT != bits <= LINEAR_BITS_LIMIT) + { + palette.set(newPalette(bits).from(palette.get())); + } + + this.bits.set(bits); + data.set(data.get().setBits(bits)); + } + } + + private static int[] computeBitLimits() { + int[] m = new int[16]; + + for(int i = 0; i < m.length; i++) + { + m[i] = (int) Math.pow(2, i); + } + + return m; + } +} diff --git a/src/main/java/com/volmit/iris/util/hunk/bits/HashPalette.java b/src/main/java/com/volmit/iris/util/hunk/bits/HashPalette.java new file mode 100644 index 000000000..c7cbd41c3 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/bits/HashPalette.java @@ -0,0 +1,74 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.bits; + +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.function.Consumer2; + +import java.util.concurrent.atomic.AtomicInteger; + +public class HashPalette implements Palette { + private final KMap palette; + private final KMap lookup; + private final AtomicInteger size; + + public HashPalette() + { + this.size = new AtomicInteger(0); + this.palette = new KMap<>(); + this.lookup = new KMap<>(); + } + + @Override + public T get(int id) { + if(id < 0 || id >= size.get()) + { + return null; + } + + return lookup.get(id); + } + + @Override + public int add(T t) { + int index = size.getAndIncrement(); + palette.put(t, index); + lookup.put(index, t); + return index; + } + + @Override + public int id(T t) { + Integer v = palette.get(t); + return v != null ? v : -1; + } + + @Override + public int size() { + return size.get(); + } + + @Override + public void iterate(Consumer2 c) { + for(T i : palette.keySet()) + { + c.accept(i, id(i)); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/hunk/bits/LinearPalette.java b/src/main/java/com/volmit/iris/util/hunk/bits/LinearPalette.java new file mode 100644 index 000000000..5a9224e09 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/bits/LinearPalette.java @@ -0,0 +1,94 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.bits; + +import com.volmit.iris.util.function.Consumer2; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.atomic.AtomicReferenceArray; + +public class LinearPalette implements Palette { + private final AtomicReference> palette; + private final AtomicInteger size; + + public LinearPalette(int initialSize) + { + this.size = new AtomicInteger(0); + this.palette = new AtomicReference<>(new AtomicReferenceArray<>(initialSize)); + } + + @Override + public T get(int id) { + if(id < 0 || id >= size.get()) + { + return null; + } + + return palette.get().get(id); + } + + @Override + public int add(T t) { + int index = size.getAndIncrement(); + grow(index + 1); + palette.get().set(index, t); + return index; + } + + private void grow(int newLength) { + if(newLength > palette.get().length()) + { + AtomicReferenceArray a = new AtomicReferenceArray<>(newLength + size.get()); + + for(int i = 0; i < palette.get().length(); i++) + { + a.set(i, palette.get().get(i)); + } + + palette.set(a); + } + } + + @Override + public int id(T t) { + for(int i = 0; i < size(); i++) + { + if(t.equals(palette.get().get(i))) + { + return i; + } + } + + return -1; + } + + @Override + public int size() { + return size.get(); + } + + @Override + public void iterate(Consumer2 c) { + for(int i = 0; i < size(); i++) + { + c.accept(palette.get().get(i), i); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/hunk/bits/Palette.java b/src/main/java/com/volmit/iris/util/hunk/bits/Palette.java new file mode 100644 index 000000000..bb4a4a1d1 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/bits/Palette.java @@ -0,0 +1,86 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.bits; + +import com.volmit.iris.util.function.Consumer2; +import com.volmit.iris.util.function.Consumer2IO; + +import java.io.DataInputStream; +import java.io.IOException; + +public interface Palette { + T get(int id); + + int add(T t); + + int id(T t); + + int size(); + + default int bits() + { + return bits(DataContainer.INITIAL_BITS); + } + + default int bits(int minBits) + { + if(size() <= DataContainer.BIT[minBits]) + { + return minBits; + } + + for(int i = 0; i < DataContainer.BIT.length; i++) + { + if(DataContainer.BIT[i] >= size()) + { + return i; + } + } + + return DataContainer.BIT.length - 1; + } + + void iterate(Consumer2 c); + + default void iterateIO(Consumer2IO c) + { + iterate((a,b)-> { + try { + c.accept(a,b); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + + default Palette from(int size, Writable writable, DataInputStream in) throws IOException { + for(int i = 0; i < size; i++) + { + add(writable.readNodeData(in)); + } + + return this; + } + + default Palette from(Palette oldPalette) + { + oldPalette.iterate((k,v) -> add(k)); + return this; + } +} diff --git a/src/main/java/com/volmit/iris/util/hunk/bits/Writable.java b/src/main/java/com/volmit/iris/util/hunk/bits/Writable.java new file mode 100644 index 000000000..937107ea5 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/hunk/bits/Writable.java @@ -0,0 +1,29 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.hunk.bits; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public interface Writable { + T readNodeData(DataInputStream din) throws IOException; + + void writeNodeData(DataOutputStream dos, T t) throws IOException; +} diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/PaletteHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/PaletteHunk.java index fcdd8a131..cadd12b21 100644 --- a/src/main/java/com/volmit/iris/util/hunk/storage/PaletteHunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/storage/PaletteHunk.java @@ -23,6 +23,8 @@ import com.volmit.iris.util.data.palette.PalettedContainer; import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.function.Consumer4IO; import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.hunk.bits.DataContainer; +import com.volmit.iris.util.hunk.bits.Writable; import lombok.Data; import lombok.EqualsAndHashCode; @@ -33,17 +35,27 @@ import java.util.Map; @Data @EqualsAndHashCode(callSuper = false) public class PaletteHunk extends StorageHunk implements Hunk { - private PalettedContainer data; + private DataContainer data; - public PaletteHunk() { - super(16, 16, 16); - data = new PalettedContainer<>(); + public PaletteHunk(int w, int h, int d, Writable writer) { + super(w,h,d); + data = new DataContainer<>(writer, w * h * d); } + + public void setPalette(DataContainer c) { + data = c; + } + + public boolean isMapped() { return false; } + private int index(int x, int y, int z) { + return (z * getWidth() * getHeight()) + (y * getWidth()) + x; + } + @Override public synchronized Hunk iterateSync(Consumer4 c) { for(int i = 0; i < getWidth(); i++) @@ -84,11 +96,11 @@ public class PaletteHunk extends StorageHunk implements Hunk { @Override public void setRaw(int x, int y, int z, T t) { - data.set(x,y,z,t); + data.set(index(x, y, z), t); } @Override public T getRaw(int x, int y, int z) { - return data.get(x,y,z); + return data.get(index(x, y, z)); } } diff --git a/src/main/java/com/volmit/iris/util/hunk/storage/PaletteOrHunk.java b/src/main/java/com/volmit/iris/util/hunk/storage/PaletteOrHunk.java index 92235aac3..0717b6066 100644 --- a/src/main/java/com/volmit/iris/util/hunk/storage/PaletteOrHunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/storage/PaletteOrHunk.java @@ -22,6 +22,8 @@ import com.volmit.iris.util.data.palette.PalettedContainer; import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.function.Consumer4IO; import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.hunk.bits.DataContainer; +import com.volmit.iris.util.hunk.bits.Writable; import java.io.IOException; import java.util.Map; @@ -29,26 +31,26 @@ import java.util.function.Supplier; public class PaletteOrHunk extends StorageHunk implements Hunk { private final Hunk hunk; - public PaletteOrHunk(int width, int height, int depth, boolean allow, Supplier> factory) { + public PaletteOrHunk(int width, int height, int depth, boolean allow, Writable writable, Supplier> factory) { super(width, height, depth); - hunk = (width == 16 && height == 16 && depth == 16 && allow) ? new PaletteHunk<>() : factory.get(); + hunk = (allow) ? new PaletteHunk<>(width, height, depth, writable) : factory.get(); } - public PalettedContainer palette() + public DataContainer palette() { return isPalette() ? ((PaletteHunk)hunk).getData() : null; } - public void palette(PalettedContainer t) - { - if(isPalette()){ - ((PaletteHunk)hunk).setData(t); + public void setPalette(DataContainer c) { + if(isPalette()) + { + ((PaletteHunk)hunk).setPalette(c); } } public boolean isPalette() { - return getWidth() == 16 && getHeight() == 16 && getDepth() == 16; + return hunk instanceof PaletteHunk; } @Override diff --git a/src/main/java/com/volmit/iris/util/hunk/view/FunctionalHunkView.java b/src/main/java/com/volmit/iris/util/hunk/view/FunctionalHunkView.java index 3629824f4..da8b4df13 100644 --- a/src/main/java/com/volmit/iris/util/hunk/view/FunctionalHunkView.java +++ b/src/main/java/com/volmit/iris/util/hunk/view/FunctionalHunkView.java @@ -36,7 +36,7 @@ public class FunctionalHunkView implements Hunk { @Override public void setRaw(int x, int y, int z, T t) { if (backConverter == null) { - throw new UnsupportedOperationException("You cannot write to this hunk (Read Only)"); + throw new UnsupportedOperationException("You cannot writeNodeData to this hunk (Read Only)"); } src.setRaw(x, y, z, backConverter.apply(t)); diff --git a/src/main/java/com/volmit/iris/util/io/IO.java b/src/main/java/com/volmit/iris/util/io/IO.java index 9d27f42e0..05db560ce 100644 --- a/src/main/java/com/volmit/iris/util/io/IO.java +++ b/src/main/java/com/volmit/iris/util/io/IO.java @@ -25,6 +25,7 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -162,6 +163,24 @@ public class IO { return new String(hexChars).toUpperCase(); } + public static String longsToHex(long[] bytes) { + byte[] v = new byte[bytes.length * 8]; + + for(int i = 0; i < bytes.length; i++) + { + v[i * 8] = (byte)(bytes[i] >>> 56); + v[(i * 8) + 1] = (byte)(bytes[i] >>> 48); + v[(i * 8) + 2] = (byte)(bytes[i] >>> 40); + v[(i * 8) + 3] = (byte)(bytes[i] >>> 32); + v[(i * 8) + 4] = (byte)(bytes[i] >>> 24); + v[(i * 8) + 5] = (byte)(bytes[i] >>> 16); + v[(i * 8) + 6] = (byte)(bytes[i] >>> 8); + v[(i * 8) + 7] = (byte)(bytes[i] >>> 0); + } + + return bytesToHex(v); + } + /** * Transfers the length of the buffer amount of data from the input stream to * the output stream @@ -239,7 +258,7 @@ public class IO { * buffer size. This does NOT close streams. * * @param in the input stream to read from - * @param out the output stream to write to + * @param out the output stream to writeNodeData to * @param bufferSize the target buffer size * @return total size transfered * @throws IOException shit happens @@ -915,7 +934,7 @@ public class IO { return new ByteArrayInputStream(bytes); } - // write byte[] + // writeNodeData byte[] // ----------------------------------------------------------------------- /** @@ -939,8 +958,8 @@ public class IO { /** * Writes bytes from a byte[] to an OutputStream. * - * @param data the byte array to write, do not modify during output, null ignored - * @param output the OutputStream to write to + * @param data the byte array to writeNodeData, do not modify during output, null ignored + * @param output the OutputStream to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -957,8 +976,8 @@ public class IO { *

* This method uses {@link String#String(byte[])}. * - * @param data the byte array to write, do not modify during output, null ignored - * @param output the Writer to write to + * @param data the byte array to writeNodeData, do not modify during output, null ignored + * @param output the Writer to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -969,7 +988,7 @@ public class IO { } } - // write char[] + // writeNodeData char[] // ----------------------------------------------------------------------- /** @@ -981,8 +1000,8 @@ public class IO { *

* This method uses {@link String#String(byte[], String)}. * - * @param data the byte array to write, do not modify during output, null ignored - * @param output the Writer to write to + * @param data the byte array to writeNodeData, do not modify during output, null ignored + * @param output the Writer to writeNodeData to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs @@ -1002,8 +1021,8 @@ public class IO { * Writes chars from a char[] to a Writer using the * default character encoding of the platform. * - * @param data the char array to write, do not modify during output, null ignored - * @param output the Writer to write to + * @param data the char array to writeNodeData, do not modify during output, null ignored + * @param output the Writer to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1020,8 +1039,8 @@ public class IO { *

* This method uses {@link String#String(char[])} and {@link String#getBytes()}. * - * @param data the char array to write, do not modify during output, null ignored - * @param output the OutputStream to write to + * @param data the char array to writeNodeData, do not modify during output, null ignored + * @param output the OutputStream to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1032,7 +1051,7 @@ public class IO { } } - // write String + // writeNodeData String // ----------------------------------------------------------------------- /** @@ -1045,8 +1064,8 @@ public class IO { * This method uses {@link String#String(char[])} and * {@link String#getBytes(String)}. * - * @param data the char array to write, do not modify during output, null ignored - * @param output the OutputStream to write to + * @param data the char array to writeNodeData, do not modify during output, null ignored + * @param output the OutputStream to writeNodeData to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs @@ -1065,8 +1084,8 @@ public class IO { /** * Writes chars from a String to a Writer. * - * @param data the String to write, null ignored - * @param output the Writer to write to + * @param data the String to writeNodeData, null ignored + * @param output the Writer to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1084,8 +1103,8 @@ public class IO { *

* This method uses {@link String#getBytes()}. * - * @param data the String to write, null ignored - * @param output the OutputStream to write to + * @param data the String to writeNodeData, null ignored + * @param output the OutputStream to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1096,7 +1115,7 @@ public class IO { } } - // write StringBuffer + // writeNodeData StringBuffer // ----------------------------------------------------------------------- /** @@ -1108,8 +1127,8 @@ public class IO { *

* This method uses {@link String#getBytes(String)}. * - * @param data the String to write, null ignored - * @param output the OutputStream to write to + * @param data the String to writeNodeData, null ignored + * @param output the OutputStream to writeNodeData to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs @@ -1128,8 +1147,8 @@ public class IO { /** * Writes chars from a StringBuffer to a Writer. * - * @param data the StringBuffer to write, null ignored - * @param output the Writer to write to + * @param data the StringBuffer to writeNodeData, null ignored + * @param output the Writer to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1147,8 +1166,8 @@ public class IO { *

* This method uses {@link String#getBytes()}. * - * @param data the StringBuffer to write, null ignored - * @param output the OutputStream to write to + * @param data the StringBuffer to writeNodeData, null ignored + * @param output the OutputStream to writeNodeData to * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1171,8 +1190,8 @@ public class IO { *

* This method uses {@link String#getBytes(String)}. * - * @param data the StringBuffer to write, null ignored - * @param output the OutputStream to write to + * @param data the StringBuffer to writeNodeData, null ignored + * @param output the OutputStream to writeNodeData to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if output is null * @throws IOException if an I/O error occurs @@ -1193,9 +1212,9 @@ public class IO { * OutputStream line by line, using the default character encoding * of the platform and the specified line ending. * - * @param lines the lines to write, null entries produce blank lines + * @param lines the lines to writeNodeData, null entries produce blank lines * @param lineEnding the line separator to use, null is system default - * @param output the OutputStream to write to, not null, not closed + * @param output the OutputStream to writeNodeData to, not null, not closed * @throws NullPointerException if the output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1224,9 +1243,9 @@ public class IO { * Character encoding names can be found at * IANA. * - * @param lines the lines to write, null entries produce blank lines + * @param lines the lines to writeNodeData, null entries produce blank lines * @param lineEnding the line separator to use, null is system default - * @param output the OutputStream to write to, not null, not closed + * @param output the OutputStream to writeNodeData to, not null, not closed * @param encoding the encoding to use, null means platform default * @throws NullPointerException if the output is null * @throws IOException if an I/O error occurs @@ -1259,9 +1278,9 @@ public class IO { * Writes the toString() value of each item in a collection to a * Writer line by line, using the specified line ending. * - * @param lines the lines to write, null entries produce blank lines + * @param lines the lines to writeNodeData, null entries produce blank lines * @param lineEnding the line separator to use, null is system default - * @param writer the Writer to write to, not null, not closed + * @param writer the Writer to writeNodeData to, not null, not closed * @throws NullPointerException if the input is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1294,7 +1313,7 @@ public class IO { * copyLarge(InputStream, OutputStream) method. * * @param input the InputStream to read from - * @param output the OutputStream to write to + * @param output the OutputStream to writeNodeData to * @return the number of bytes copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs @@ -1317,7 +1336,7 @@ public class IO { * BufferedInputStream. * * @param input the InputStream to read from - * @param output the OutputStream to write to + * @param output the OutputStream to writeNodeData to * @return the number of bytes copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs @@ -1344,7 +1363,7 @@ public class IO { * This method uses {@link InputStreamReader}. * * @param input the InputStream to read from - * @param output the Writer to write to + * @param output the Writer to writeNodeData to * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1370,7 +1389,7 @@ public class IO { * This method uses {@link InputStreamReader}. * * @param input the InputStream to read from - * @param output the Writer to write to + * @param output the Writer to writeNodeData to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs @@ -1397,7 +1416,7 @@ public class IO { * copyLarge(Reader, Writer) method. * * @param input the Reader to read from - * @param output the Writer to write to + * @param output the Writer to writeNodeData to * @return the number of characters copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs @@ -1420,7 +1439,7 @@ public class IO { * BufferedReader. * * @param input the Reader to read from - * @param output the Writer to write to + * @param output the Writer to writeNodeData to * @return the number of characters copied * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs @@ -1451,7 +1470,7 @@ public class IO { * This method uses {@link OutputStreamWriter}. * * @param input the Reader to read from - * @param output the OutputStream to write to + * @param output the OutputStream to writeNodeData to * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs * @since Commons IO 1.1 @@ -1483,7 +1502,7 @@ public class IO { * This method uses {@link OutputStreamWriter}. * * @param input the Reader to read from - * @param output the OutputStream to write to + * @param output the OutputStream to writeNodeData to * @param encoding the encoding to use, null means platform default * @throws NullPointerException if the input or output is null * @throws IOException if an I/O error occurs diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 88149846a..481eaa808 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * The mantle can store any type of data slice anywhere and manage regions & IO on it's own. - * This class is fully thread safe read & write + * This class is fully thread safe read & writeNodeData */ public class Mantle { private final File dataFolder; @@ -335,7 +335,7 @@ public class Mantle { } /** - * Closes the Mantle. By closing the mantle, you can no longer read or write + * Closes the Mantle. By closing the mantle, you can no longer read or writeNodeData * any data to the mantle or it's Tectonic Plates. Closing will also flush any * loaded regions to the disk in parallel. */ diff --git a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java index c1e648a13..403e8818f 100644 --- a/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java +++ b/src/main/java/com/volmit/iris/util/mantle/TectonicPlate.java @@ -163,7 +163,7 @@ public class TectonicPlate { /** * Write this tectonic plate to file * - * @param file the file to write it to + * @param file the file to writeNodeData it to * @throws IOException shit happens */ public void write(File file) throws IOException { diff --git a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java index c5f96b185..d187cacdc 100644 --- a/src/main/java/com/volmit/iris/util/matter/MatterSlice.java +++ b/src/main/java/com/volmit/iris/util/matter/MatterSlice.java @@ -26,6 +26,8 @@ import com.volmit.iris.util.data.palette.Palette; import com.volmit.iris.util.data.palette.PaletteType; import com.volmit.iris.util.data.palette.PalettedContainer; import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.hunk.bits.DataContainer; +import com.volmit.iris.util.hunk.bits.Writable; import com.volmit.iris.util.hunk.storage.PaletteOrHunk; import org.bukkit.Location; import org.bukkit.World; @@ -39,7 +41,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -public interface MatterSlice extends Hunk, PaletteType { +public interface MatterSlice extends Hunk, PaletteType, Writable { Class getType(); Palette getGlobalPalette(); @@ -49,11 +51,21 @@ public interface MatterSlice extends Hunk, PaletteType { writeNode(s, dos); } + @Override + default void writeNodeData(DataOutputStream dos, T s) throws IOException { + writeNode(s, dos); + } + @Override default T readPaletteNode(DataInputStream din) throws IOException { return readNode(din); } + @Override + default T readNodeData(DataInputStream din) throws IOException { + return readNode(din); + } + default void applyFilter(MatterFilter filter) { updateSync(filter::update); } @@ -154,22 +166,7 @@ public interface MatterSlice extends Hunk, PaletteType { dos.writeUTF(getType().getCanonicalName()); if((this instanceof PaletteOrHunk f && f.isPalette())) { - PalettedContainer c = f.palette(); - List palette = new ArrayList<>(); - long[] data = c.write(palette); - - Varint.writeUnsignedVarInt(palette.size(), dos); - for(T i : palette) - { - writeNode(i, dos); - } - - Varint.writeUnsignedVarInt(data.length, dos); - for(long i : data) - { - dos.writeLong(i); - } - + f.palette().writeDos(dos); return; } @@ -194,24 +191,7 @@ public interface MatterSlice extends Hunk, PaletteType { default void read(DataInputStream din) throws IOException { if((this instanceof PaletteOrHunk f && f.isPalette())) { - PalettedContainer c = new PalettedContainer<>(); - List palette = new ArrayList<>(); - int ps = Varint.readUnsignedVarInt(din); - - for(int i = 0; i < ps; i++) - { - palette.add(readNode(din)); - } - - int ds = Varint.readUnsignedVarInt(din); - long[] data = new long[ds]; - for(int i = 0; i < ds; i++) - { - data[i] = din.readLong(); - } - - c.read(palette, data); - + f.setPalette(DataContainer.readDin(din, this)); return; } diff --git a/src/main/java/com/volmit/iris/util/matter/MatterTest.java b/src/main/java/com/volmit/iris/util/matter/MatterTest.java new file mode 100644 index 000000000..54b0af432 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/matter/MatterTest.java @@ -0,0 +1,74 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.matter; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.NoiseStyle; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.palette.PalettedContainer; +import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.noise.CNG; +import org.checkerframework.checker.units.qual.K; + +import java.util.Arrays; +import java.util.List; + +public class MatterTest { + public static void test() + { + CNG cng = NoiseStyle.STATIC.create(new RNG(1337)); + PalettedContainer p = new PalettedContainer<>(); + + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 16; j++) + { + for(int k = 0; k < 16; k++) + { + p.set(i,j,k,cng.fit(1, 3, i,j,k)); + } + } + } + + KList palette = new KList<>(); + long[] data = p.write(palette); + + Iris.info("RAW PALE: " + palette.toString(",")); + Iris.info("RAW DATA: " + IO.longsToHex(data)); + + PalettedContainer px = new PalettedContainer<>(); + px.read(palette, data); + + KList palette2 = new KList<>(); + long[] data2 = px.write(palette); + + if(Arrays.equals(data, data2)) + { + Iris.info("Correct! All data matches!"); + } + + else + { + Iris.warn("No match"); + Iris.error("RAW PALE: " + palette2.toString(",")); + Iris.error("RAW DATA: " + IO.longsToHex(data2)); + } + } +} diff --git a/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java b/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java index d7f1ccdae..40fcc644b 100644 --- a/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java +++ b/src/main/java/com/volmit/iris/util/matter/slices/RawMatter.java @@ -37,7 +37,7 @@ public abstract class RawMatter extends PaletteOrHunk implements MatterSli private final Class type; public RawMatter(int width, int height, int depth, Class type) { - super(width, height, depth, true, () -> new MappedHunk<>(width, height, depth)); + super(width, height, depth, false, this, () -> new MappedHunk<>(width, height, depth)); writers = new KMap<>(); readers = new KMap<>(); this.type = type; diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/MCAFile.java b/src/main/java/com/volmit/iris/util/nbt/mca/MCAFile.java index d034fb4d0..47eb5f630 100644 --- a/src/main/java/com/volmit/iris/util/nbt/mca/MCAFile.java +++ b/src/main/java/com/volmit/iris/util/nbt/mca/MCAFile.java @@ -135,7 +135,7 @@ public class MCAFile { /** * Calls {@link MCAFile#serialize(RandomAccessFile, boolean)} without updating any timestamps. * - * @param raf The {@code RandomAccessFile} to write to. + * @param raf The {@code RandomAccessFile} to writeNodeData to. * @return The amount of chunks written to the file. * @throws IOException If something went wrong during serialization. * @see MCAFile#serialize(RandomAccessFile, boolean) @@ -148,7 +148,7 @@ public class MCAFile { * Serializes this object to an .mca file. * This method does not perform any cleanups on the data. * - * @param raf The {@code RandomAccessFile} to write to. + * @param raf The {@code RandomAccessFile} to writeNodeData to. * @param changeLastUpdate Whether it should update all timestamps that show * when this file was last updated. * @return The amount of chunks written to the file. @@ -190,7 +190,7 @@ public class MCAFile { raf.writeByte(globalOffset & 0xFF); raf.writeByte(sectors); - // write timestamp + // writeNodeData timestamp raf.seek(index * 4L + 4096); raf.writeInt(changeLastUpdate ? timestamp : chunk.getLastMCAUpdate()); diff --git a/src/main/java/com/volmit/iris/util/nbt/mca/MCAUtil.java b/src/main/java/com/volmit/iris/util/nbt/mca/MCAUtil.java index d2240fbd8..eb6f61f1c 100644 --- a/src/main/java/com/volmit/iris/util/nbt/mca/MCAUtil.java +++ b/src/main/java/com/volmit/iris/util/nbt/mca/MCAUtil.java @@ -30,7 +30,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * Provides main and utility functions to read and write .mca files and + * Provides main and utility functions to read and writeNodeData .mca files and * to convert block, chunk and region coordinates. */ public final class MCAUtil { @@ -98,8 +98,8 @@ public final class MCAUtil { /** * Calls {@link MCAUtil#write(MCAFile, File, boolean)} without changing the timestamps. * - * @param file The file to write to. - * @param mcaFile The data of the MCA file to write. + * @param file The file to writeNodeData to. + * @param mcaFile The data of the MCA file to writeNodeData. * @return The amount of chunks written to the file. * @throws IOException If something goes wrong during serialization. * @see MCAUtil#write(MCAFile, File, boolean) @@ -111,8 +111,8 @@ public final class MCAUtil { /** * Calls {@link MCAUtil#write(MCAFile, File, boolean)} without changing the timestamps. * - * @param file The file to write to. - * @param mcaFile The data of the MCA file to write. + * @param file The file to writeNodeData to. + * @param mcaFile The data of the MCA file to writeNodeData. * @return The amount of chunks written to the file. * @throws IOException If something goes wrong during serialization. * @see MCAUtil#write(MCAFile, File, boolean) @@ -122,8 +122,8 @@ public final class MCAUtil { } /** - * @param file The file to write to. - * @param mcaFile The data of the MCA file to write. + * @param file The file to writeNodeData to. + * @param mcaFile The data of the MCA file to writeNodeData. * @param changeLastUpdate Whether to adjust the timestamps of when the file was saved. * @return The amount of chunks written to the file. * @throws IOException If something goes wrong during serialization. @@ -139,8 +139,8 @@ public final class MCAUtil { * the value set by either loading an already existing MCA file or setting them manually.
* If the file already exists, it is completely overwritten by the new file (no modification). * - * @param file The file to write to. - * @param mcaFile The data of the MCA file to write. + * @param file The file to writeNodeData to. + * @param mcaFile The data of the MCA file to writeNodeData. * @param changeLastUpdate Whether to adjust the timestamps of when the file was saved. * @return The amount of chunks written to the file. * @throws IOException If something goes wrong during serialization.