Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

+ implemented serialization handlers using ByteBuffers for every tera…

… array

+ implemented benchmarks for different ways of serializing tera arrays
+ added Chunks.proto describing simple messages for chunks and tera arrays
- removed stream based serialization handlers due to massive performance problems
  • Loading branch information...
commit 0a0f69ca07cfc9b73d1a6d946e705d9370137a0f 1 parent ef90f9e
@mbrotz mbrotz authored
Showing with 704 additions and 241 deletions.
  1. 0  protobuf/compiler/protoc.exe
  2. +48 −0 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArrayDeserializeFromBuffer.java
  3. +40 −0 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerialization.java
  4. +53 −0 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeObject.java
  5. +48 −0 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeToBuffer.java
  6. +58 −0 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeToStreamViaByteArray.java
  7. +62 −0 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeToStreamViaChannel.java
  8. +13 −1 src/dev/java/org/terasology/benchmark/chunks/arrays/TeraArraysBenchmark.java
  9. +9 −9 src/main/java/org/terasology/config/AdvancedConfig.java
  10. +20 −0 src/main/java/org/terasology/io/SerializationHandler.java
  11. +71 −35 src/main/java/org/terasology/world/chunks/blockdata/TeraArray.java
  12. +0 −19 src/main/java/org/terasology/world/chunks/blockdata/TeraArrayFactory.java
  13. +0 −23 src/main/java/org/terasology/world/chunks/blockdata/TeraArraySerializationHandler.java
  14. +36 −20 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArray16Bit.java
  15. +15 −3 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArray4Bit.java
  16. +15 −3 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArray8Bit.java
  17. +26 −17 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArrayByte.java
  18. +74 −52 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArray16Bit.java
  19. +13 −4 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArray4Bit.java
  20. +14 −5 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArray8Bit.java
  21. +57 −50 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArrayByte.java
  22. +32 −0 src/main/protobuf/Chunks.proto
View
0  protobuf/compiler/protoc.exe 100644 → 100755
File mode changed
View
48 .../java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArrayDeserializeFromBuffer.java
@@ -0,0 +1,48 @@
+package org.terasology.benchmark.chunks.arrays;
+
+import java.nio.ByteBuffer;
+
+import org.terasology.benchmark.BenchmarkResult;
+import org.terasology.world.chunks.blockdata.TeraArray;
+import org.terasology.world.chunks.blockdata.TeraArray.SerializationHandler;
+
+public class BenchmarkTeraArrayDeserializeFromBuffer extends BenchmarkTeraArraySerialization {
+
+ protected ByteBuffer buffer;
+
+ @SuppressWarnings("rawtypes")
+ public BenchmarkTeraArrayDeserializeFromBuffer(SerializationHandler handler, TeraArray array) {
+ super(handler, array);
+ }
+
+ @Override
+ public String getTitle() {
+ return array.getClass().getSimpleName() + " deserialization from buffer";
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setup() {
+ buffer = ByteBuffer.allocate(BUFFER_SIZE);
+ handler.serialize(array, buffer);
+ buffer.rewind();
+ }
+
+ @Override
+ public void prerun(int index) {}
+
+ @Override
+ public int run(int index, int repetitions, BenchmarkResult result) {
+ for (int i = 0; i < repetitions; i++) {
+ handler.deserialize(buffer);
+ buffer.rewind();
+ }
+ return 0;
+ }
+
+ @Override
+ public void postrun(int index, BenchmarkResult result) {}
+
+ @Override
+ public void finish(boolean aborted) {}
+}
View
40 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerialization.java
@@ -0,0 +1,40 @@
+package org.terasology.benchmark.chunks.arrays;
+
+import org.terasology.benchmark.BasicBenchmarkResult;
+import org.terasology.benchmark.Benchmark;
+import org.terasology.benchmark.BenchmarkResult;
+import org.terasology.world.chunks.blockdata.TeraArray;
+
+import com.google.common.base.Preconditions;
+
+@SuppressWarnings("rawtypes")
+public abstract class BenchmarkTeraArraySerialization extends Benchmark {
+
+ public static final int BUFFER_SIZE = 1024 * 1024;
+
+ public final TeraArray.SerializationHandler handler;
+ public final TeraArray array;
+
+ @SuppressWarnings("unchecked")
+ public BenchmarkTeraArraySerialization(TeraArray.SerializationHandler handler, TeraArray array) {
+ this.handler = Preconditions.checkNotNull(handler);
+ this.array = Preconditions.checkNotNull(array);
+ Preconditions.checkArgument(handler.canHandle(array.getClass()), "The supplied serialization handler is incompatible to the supplied array");
+ }
+
+ @Override
+ public int getWarmupRepetitions() {
+ return 10000;
+ }
+
+ @Override
+ public int[] getRepetitions() {
+ return new int[] {1000, 5000, 10000};
+ }
+
+ @Override
+ public BenchmarkResult createResult() {
+ return new BasicBenchmarkResult(this);
+ }
+
+}
View
53 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeObject.java
@@ -0,0 +1,53 @@
+package org.terasology.benchmark.chunks.arrays;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import org.terasology.benchmark.BenchmarkResult;
+import org.terasology.world.chunks.blockdata.TeraArray;
+import org.terasology.world.chunks.blockdata.TeraArray.SerializationHandler;
+
+public class BenchmarkTeraArraySerializeObject extends BenchmarkTeraArraySerialization {
+
+ protected ByteArrayOutputStream out;
+
+ @SuppressWarnings("rawtypes")
+ public BenchmarkTeraArraySerializeObject(SerializationHandler handler, TeraArray array) {
+ super(handler, array);
+ }
+
+ @Override
+ public String getTitle() {
+ return array.getClass().getSimpleName() + " builtin object serialization directly into ByteArrayOutputStream";
+ }
+
+ @Override
+ public void setup() {
+ out = new ByteArrayOutputStream(BUFFER_SIZE);
+ }
+
+ @Override
+ public void prerun(int index) {}
+
+ @Override
+ public int run(int index, int repetitions, BenchmarkResult result) {
+ try {
+ int bogus = 0;
+ for (int i = 0; i < repetitions; i++) {
+ (new ObjectOutputStream(out)).writeObject(array);
+ bogus += out.size();
+ out.reset();
+ }
+ return bogus;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void postrun(int index, BenchmarkResult result) {}
+
+ @Override
+ public void finish(boolean aborted) {}
+}
View
48 src/dev/java/org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeToBuffer.java
@@ -0,0 +1,48 @@
+package org.terasology.benchmark.chunks.arrays;
+
+import java.nio.ByteBuffer;
+
+import org.terasology.benchmark.BenchmarkResult;
+import org.terasology.world.chunks.blockdata.TeraArray;
+import org.terasology.world.chunks.blockdata.TeraArray.SerializationHandler;
+
+@SuppressWarnings("rawtypes")
+public class BenchmarkTeraArraySerializeToBuffer extends BenchmarkTeraArraySerialization {
+
+ protected ByteBuffer buffer;
+
+ public BenchmarkTeraArraySerializeToBuffer(SerializationHandler handler, TeraArray array) {
+ super(handler, array);
+ }
+
+ @Override
+ public String getTitle() {
+ return array.getClass().getSimpleName() + " serialization directly into ByteBuffer";
+ }
+
+ @Override
+ public void setup() {
+ buffer = ByteBuffer.allocate(BUFFER_SIZE);
+ }
+
+ @Override
+ public void prerun(int index) {}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public int run(int index, int repetitions, BenchmarkResult result) {
+ int bogus = 0;
+ for (int i = 0; i < repetitions; i++) {
+ handler.serialize(array, buffer);
+ bogus += buffer.position();
+ buffer.rewind();
+ }
+ return bogus;
+ }
+
+ @Override
+ public void postrun(int index, BenchmarkResult result) {}
+
+ @Override
+ public void finish(boolean aborted) {}
+}
View
58 ...g/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeToStreamViaByteArray.java
@@ -0,0 +1,58 @@
+package org.terasology.benchmark.chunks.arrays;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+
+import org.terasology.benchmark.BenchmarkResult;
+import org.terasology.world.chunks.blockdata.TeraArray;
+import org.terasology.world.chunks.blockdata.TeraArray.SerializationHandler;
+
+public class BenchmarkTeraArraySerializeToStreamViaByteArray extends BenchmarkTeraArraySerialization {
+
+ protected ByteBuffer buffer;
+ protected ByteArrayOutputStream out;
+ protected byte[] via;
+
+ @SuppressWarnings("rawtypes")
+ public BenchmarkTeraArraySerializeToStreamViaByteArray(SerializationHandler handler, TeraArray array) {
+ super(handler, array);
+ }
+
+ @Override
+ public String getTitle() {
+ return array.getClass().getSimpleName() + " serialization into ByteBuffer and transfer via byte[] array into ByteArrayOutputStream";
+ }
+
+ @Override
+ public void setup() {
+ buffer = ByteBuffer.allocate(BUFFER_SIZE);
+ out = new ByteArrayOutputStream(BUFFER_SIZE);
+ via = new byte[BUFFER_SIZE];
+ }
+
+ @Override
+ public void prerun(int index) {}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public int run(int index, int repetitions, BenchmarkResult result) {
+ int bogus = 0;
+ for (int i = 0; i < repetitions; i++) {
+ handler.serialize(array, buffer);
+ final int length = buffer.position();
+ buffer.rewind();
+ buffer.get(via, 0, length);
+ buffer.rewind();
+ out.write(via, 0, length);
+ out.reset();
+ bogus += length;
+ }
+ return bogus;
+ }
+
+ @Override
+ public void postrun(int index, BenchmarkResult result) {}
+
+ @Override
+ public void finish(boolean aborted) {}
+}
View
62 ...org/terasology/benchmark/chunks/arrays/BenchmarkTeraArraySerializeToStreamViaChannel.java
@@ -0,0 +1,62 @@
+package org.terasology.benchmark.chunks.arrays;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+
+import org.terasology.benchmark.BenchmarkResult;
+import org.terasology.world.chunks.blockdata.TeraArray;
+
+public class BenchmarkTeraArraySerializeToStreamViaChannel extends BenchmarkTeraArraySerialization {
+
+ protected ByteBuffer buffer;
+ protected ByteArrayOutputStream out;
+ protected WritableByteChannel channel;
+
+ @SuppressWarnings("rawtypes")
+ public BenchmarkTeraArraySerializeToStreamViaChannel(TeraArray.SerializationHandler handler, TeraArray array) {
+ super(handler, array);
+ }
+
+ @Override
+ public String getTitle() {
+ return array.getClass().getSimpleName() + " serialization into ByteBuffer and transfer via Channel into ByteArrayOutputStream";
+ }
+
+ @Override
+ public void setup() {
+ buffer = ByteBuffer.allocate(BUFFER_SIZE);
+ out = new ByteArrayOutputStream(BUFFER_SIZE);
+ channel = Channels.newChannel(out);
+ }
+
+ @Override
+ public void prerun(int index) {}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public int run(int index, int repetitions, BenchmarkResult result) {
+ try {
+ int bogus = 0;
+ for (int i = 0; i < repetitions; i++) {
+ handler.serialize(array, buffer);
+ bogus += buffer.position();
+ buffer.rewind();
+ channel.write(buffer);
+ buffer.rewind();
+ out.reset();
+ }
+ return bogus;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void postrun(int index, BenchmarkResult result) {}
+
+ @Override
+ public void finish(boolean aborted) {}
+}
View
14 src/dev/java/org/terasology/benchmark/chunks/arrays/TeraArraysBenchmark.java
@@ -1,11 +1,15 @@
package org.terasology.benchmark.chunks.arrays;
+import java.io.ByteArrayOutputStream;
import java.util.LinkedList;
import java.util.List;
import org.terasology.benchmark.Benchmark;
import org.terasology.benchmark.PrintToConsoleCallback;
import org.terasology.benchmark.Benchmarks;
+import org.terasology.utilities.FastRandom;
+import org.terasology.world.chunks.blockdata.TeraArray;
+import org.terasology.world.chunks.blockdata.TeraDenseArray16Bit;
import org.terasology.world.chunks.blockdata.TeraDenseArray4Bit;
import org.terasology.world.chunks.blockdata.TeraDenseArray8Bit;
import org.terasology.world.chunks.blockdata.TeraSparseArray4Bit;
@@ -40,7 +44,15 @@ private TeraArraysBenchmark() {}
public static void main(String[] args) {
final List<Benchmark> benchmarks = new LinkedList<Benchmark>();
-
+
+// benchmarks.add(new BenchmarkTeraArraySerializeObject(new TeraDenseArray8Bit.SerializationHandler(), new TeraDenseArray8Bit(16, 256, 16)));
+// benchmarks.add(new BenchmarkTeraArraySerializeToBuffer(new TeraDenseArray8Bit.SerializationHandler(), new TeraDenseArray8Bit(16, 256, 16)));
+// benchmarks.add(new BenchmarkTeraArraySerializeToStreamViaByteArray(new TeraDenseArray8Bit.SerializationHandler(), new TeraDenseArray8Bit(16, 256, 16)));
+// benchmarks.add(new BenchmarkTeraArraySerializeToStreamViaChannel(new TeraDenseArray8Bit.SerializationHandler(), new TeraDenseArray8Bit(16, 256, 16)));
+//
+// benchmarks.add(new BenchmarkTeraArrayDeserializeFromBuffer(new TeraDenseArray8Bit.SerializationHandler(), new TeraDenseArray8Bit(16, 256, 16)));
+//
+//
// benchmarks.add(new BenchmarkTeraArrayRead(new TeraDenseArray8Bit(16, 256, 16)));
// benchmarks.add(new BenchmarkTeraArrayRead(new TeraDenseArray4Bit(16, 256, 16)));
// benchmarks.add(new BenchmarkTeraArrayRead(new TeraSparseArray8Bit(16, 256, 16, inflated8Bit, deflated8Bit)));
View
18 src/main/java/org/terasology/config/AdvancedConfig.java
@@ -6,7 +6,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.terasology.world.chunks.blockdata.TeraArrayFactory;
+import org.terasology.world.chunks.blockdata.TeraArray;
import org.terasology.world.chunks.blockdata.TeraDenseArray16Bit;
import org.terasology.world.chunks.blockdata.TeraDenseArray4Bit;
import org.terasology.world.chunks.blockdata.TeraDenseArray8Bit;
@@ -34,7 +34,7 @@
public final class AdvancedConfig {
private static final Logger logger = LoggerFactory.getLogger(AdvancedConfig.class);
- private static final Map<String, TeraArrayFactory> teraArrayRegistry;
+ private static final Map<String, TeraArray.Factory> teraArrayRegistry;
private String blocksFactory, sunlightFactory, lightFactory, liquidFactory;
private boolean chunkDeflationEnabled, chunkDeflationLoggingEnabled;
@@ -45,7 +45,7 @@ public String getBlocksFactoryName() {
return blocksFactory;
}
- public TeraArrayFactory getBlocksFactory() {
+ public TeraArray.Factory getBlocksFactory() {
return requireTeraArrayFactory(blocksFactory);
}
@@ -68,7 +68,7 @@ public String getSunlightFactoryName() {
return sunlightFactory;
}
- public TeraArrayFactory getSunlightFactory() {
+ public TeraArray.Factory getSunlightFactory() {
return requireTeraArrayFactory(sunlightFactory);
}
@@ -91,7 +91,7 @@ public String getLightFactoryName() {
return lightFactory;
}
- public TeraArrayFactory getLightFactory() {
+ public TeraArray.Factory getLightFactory() {
return requireTeraArrayFactory(lightFactory);
}
@@ -114,7 +114,7 @@ public String getLiquidFactoryName() {
return liquidFactory;
}
- public TeraArrayFactory getLiquidFactory() {
+ public TeraArray.Factory getLiquidFactory() {
return requireTeraArrayFactory(liquidFactory);
}
@@ -200,12 +200,12 @@ public JsonElement serialize(AdvancedConfig src, Type typeOfSrc, JsonSerializati
registerTeraArrayFactory(new TeraSparseArray16Bit.Factory());
}
- public static TeraArrayFactory getTeraArrayFactory(String factory) {
+ public static TeraArray.Factory getTeraArrayFactory(String factory) {
Preconditions.checkNotNull(factory, "The parameter 'factory' must not be null");
return teraArrayRegistry.get(factory);
}
- public static TeraArrayFactory requireTeraArrayFactory(String factory) {
+ public static TeraArray.Factory requireTeraArrayFactory(String factory) {
Preconditions.checkNotNull(factory, "Parameter 'factory' must no be null");
return Preconditions.checkNotNull(teraArrayRegistry.get(factory), "Factory does not exist: '" + factory + "'");
}
@@ -230,7 +230,7 @@ public static boolean containsTeraArrayFactory(String factory) {
return factories;
}
- public static void registerTeraArrayFactory(TeraArrayFactory factory) {
+ public static void registerTeraArrayFactory(TeraArray.Factory factory) {
Preconditions.checkNotNull(factory, "Parameter 'factory' must not be null");
final String name = factory.getArrayClass().getName();
Preconditions.checkNotNull(name, "Factory:getName() must not return null");
View
20 src/main/java/org/terasology/io/SerializationHandler.java
@@ -0,0 +1,20 @@
+package org.terasology.io;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The basic interface for serialization handlers.
+ *
+ * @author Manuel Brotz <manu.brotz@gmx.ch>
+ *
+ */
+public interface SerializationHandler<T> {
+
+ public boolean canHandle(Class<?> clazz);
+
+ public int computeMinimumBufferSize(T object);
+
+ public ByteBuffer serialize(T object, ByteBuffer buffer);
+
+ public T deserialize(ByteBuffer buffer);
+}
View
106 src/main/java/org/terasology/world/chunks/blockdata/TeraArray.java
@@ -1,13 +1,11 @@
package org.terasology.world.chunks.blockdata;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.Externalizable;
import java.io.IOException;
-import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import java.io.OutputStream;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
import org.terasology.world.chunks.deflate.TeraVisitingDeflator;
@@ -50,7 +48,42 @@ protected final int pos(int x, int z) {
protected abstract void initialize();
-
+ /**
+ * This is the interface for tera array factories. Every tera array is required to implement a factory.
+ * It should be implemented as a static subclass of the corresponding tera array class and it should be called Factory.
+ *
+ * @author Manuel Brotz <manu.brotz@gmx.ch>
+ * @see org.terasology.world.chunks.blockdata.TeraDenseArray16Bit.Factory
+ *
+ */
+ public static interface Factory<T extends TeraArray> {
+
+ public Class<T> getArrayClass();
+
+ public T create();
+
+ public T create(int sizeX, int sizeY, int sizeZ);
+
+ }
+
+ /**
+ * This is the interface for serialization handlers for tera arrays. Every tera array is required to implement
+ * a serialization handler. It is recommended to subclass {@link org.terasology.world.chunks.blockdata.TeraArray.BasicSerializationHandler TeraArray.BasicSerializationHandler}
+ * instead of using this interface directly. It should be implemented as a static subclass of the corresponding tera array class.
+ *
+ * @author Manuel Brotz <manu.brotz@gmx.ch>
+ * @see org.terasology.world.chunks.blockdata.TeraArray.BasicSerializationHandler
+ */
+ public static interface SerializationHandler<T extends TeraArray> extends org.terasology.io.SerializationHandler<T> {
+
+ public int computeMinimumBufferSize(T array);
+
+ public ByteBuffer serialize(T array, ByteBuffer buffer);
+
+ public T deserialize(ByteBuffer buffer);
+
+ }
+
/**
* Extending this class is the recommended way to implement serialization handlers for tera arrays.
* Tera arrays should implement their serialization handlers as a static subclass called SerializationHandler.
@@ -60,47 +93,50 @@ protected final int pos(int x, int z) {
* @see org.terasology.world.chunks.blockdata.TeraDenseArray16Bit.Factory
*
*/
- protected static abstract class SerializationHandler<T extends TeraArray> implements TeraArraySerializationHandler<T> {
+ protected static abstract class BasicSerializationHandler<T extends TeraArray> implements SerializationHandler<T> {
- protected abstract void internalSerialize(T array, DataOutputStream out) throws IOException;
+ protected abstract int internalComputeMinimumBufferSize(T array);
- protected abstract void internalDeserialize(T array, DataInputStream in) throws IOException;
+ protected abstract void internalSerialize(T array, ByteBuffer buffer);
+
+ protected abstract T internalDeserialize(int sizeX, int sizeY, int sizeZ, ByteBuffer buffer);
@Override
- public final void serialize(T array, OutputStream out) throws IOException {
+ public final int computeMinimumBufferSize(T array) {
Preconditions.checkNotNull(array, "The parameter 'array' must not be null");
- Preconditions.checkNotNull(out, "The parameter 'out' must not be null");
- final DataOutputStream dout = new DataOutputStream(out);
- try {
- dout.writeInt(array.sizeX);
- dout.writeInt(array.sizeY);
- dout.writeInt(array.sizeZ);
- internalSerialize(array, dout);
- dout.flush();
- } finally {
- dout.close();
+ return 16 + internalComputeMinimumBufferSize(array);
+ }
+
+ @Override
+ public final ByteBuffer serialize(T array, ByteBuffer buffer) {
+ Preconditions.checkNotNull(array, "The parameter 'array' must not be null");
+ Preconditions.checkArgument(canHandle(array.getClass()), "Unable to handle the supplied array (" + array.getClass().getName() + ")");
+ if (buffer == null) {
+ buffer = ByteBuffer.allocateDirect(computeMinimumBufferSize(array));
}
+ final int lengthPos = buffer.position();
+ buffer.putInt(0);
+ buffer.putInt(array.getSizeX());
+ buffer.putInt(array.getSizeY());
+ buffer.putInt(array.getSizeZ());
+ internalSerialize(array, buffer);
+ buffer.putInt(lengthPos, buffer.position() - lengthPos - 4);
+ return buffer;
}
@Override
- public final T deserialize(TeraArrayFactory<T> factory, InputStream in) throws IOException {
- Preconditions.checkNotNull(factory, "The parameter 'factory' must not be null");
- Preconditions.checkNotNull(in, "The parameter 'in' must not be null");
- final DataInputStream din = new DataInputStream(in);
- try {
- int sizeX = din.readInt();
- int sizeY = din.readInt();
- int sizeZ = din.readInt();
- T array = Preconditions.checkNotNull(factory.create(sizeX, sizeY, sizeZ), "TeraArrayFactory<T>:create(int, int, int) must not return null");
- internalDeserialize(array, din);
- return array;
- } finally {
- din.close();
- }
+ public final T deserialize(ByteBuffer buffer) {
+ Preconditions.checkNotNull(buffer, "The parameter 'buffer' must not be null");
+ final int length = buffer.getInt();
+ if (buffer.remaining() < length)
+ throw new BufferUnderflowException();
+ final int sizeX = buffer.getInt();
+ final int sizeY = buffer.getInt();
+ final int sizeZ = buffer.getInt();
+ return internalDeserialize(sizeX, sizeY, sizeZ, buffer);
}
-
}
-
+
protected TeraArray() {}
protected TeraArray(int sizeX, int sizeY, int sizeZ, boolean initialize) {
View
19 src/main/java/org/terasology/world/chunks/blockdata/TeraArrayFactory.java
@@ -1,19 +0,0 @@
-package org.terasology.world.chunks.blockdata;
-
-/**
- * This is the interface for tera array factories. Every tera array is required to implement a factory.
- * It should be implemented as a static subclass of the corresponding tera array class and it should be called Factory.
- *
- * @author Manuel Brotz <manu.brotz@gmx.ch>
- * @see org.terasology.world.chunks.blockdata.TeraDenseArray16Bit.Factory
- *
- */
-public interface TeraArrayFactory<T extends TeraArray> {
-
- public Class<T> getArrayClass();
-
- public T create();
-
- public T create(int sizeX, int sizeY, int sizeZ);
-
-}
View
23 src/main/java/org/terasology/world/chunks/blockdata/TeraArraySerializationHandler.java
@@ -1,23 +0,0 @@
-package org.terasology.world.chunks.blockdata;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * This is the interface for serialization handlers for tera arrays. Every tera array is required to implement
- * a serialization handler. It is recommended to subclass {@link org.terasology.world.chunks.blockdata.TeraArray.SerializationHandler TeraArray.SerializationHandler}
- * instead of using this interface directly. It should be implemented as a static subclass of the corresponding tera array class.
- *
- * @author Manuel Brotz <manu.brotz@gmx.ch>
- * @see org.terasology.world.chunks.blockdata.TeraArray.SerializationHandler
- */
-public interface TeraArraySerializationHandler<T extends TeraArray> {
-
- public Class<T> getArrayClass();
-
- public void serialize(T array, OutputStream out) throws IOException;
-
- public T deserialize(TeraArrayFactory<T> factory, InputStream in) throws IOException;
-
-}
View
56 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArray16Bit.java
@@ -1,10 +1,10 @@
package org.terasology.world.chunks.blockdata;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
import org.terasology.world.chunks.deflate.TeraVisitingDeflator;
@@ -26,45 +26,61 @@ protected void initialize() {
this.data = new short[getSizeXYZ()];
}
- public static class SerializationHandler extends TeraArray.SerializationHandler<TeraDenseArray16Bit> {
+ public static class SerializationHandler extends TeraArray.BasicSerializationHandler<TeraDenseArray16Bit> {
+
@Override
- public Class<TeraDenseArray16Bit> getArrayClass() {
- return TeraDenseArray16Bit.class;
+ public boolean canHandle(Class<?> clazz) {
+ return TeraDenseArray16Bit.class.equals(clazz);
}
+
@Override
- protected void internalSerialize(TeraDenseArray16Bit array, DataOutputStream out) throws IOException {
+ protected int internalComputeMinimumBufferSize(TeraDenseArray16Bit array) {
+ final short[] data = array.data;
+ if (data == null)
+ return 4;
+ else
+ return 4 + data.length;
+ }
+
+ @Override
+ protected void internalSerialize(TeraDenseArray16Bit array, ByteBuffer buffer) {
final short[] data = array.data;
if (data == null)
- out.writeInt(0);
+ buffer.putInt(0);
else {
- out.writeInt(data.length);
- for (short s : data) {
- out.writeShort(s);
- }
+ buffer.putInt(data.length);
+ final ShortBuffer sbuffer = buffer.asShortBuffer();
+ sbuffer.put(data);
+ buffer.position(buffer.position() + data.length * 2);
}
}
+
@Override
- protected void internalDeserialize(TeraDenseArray16Bit array, DataInputStream in) throws IOException {
- final short[] data = array.data;
- final int length = in.readInt();
- Preconditions.checkNotNull(data);
- if (data.length != length)
- throw new IOException("The size of the array (" + data.length + ") does not match the size of the stored data (" + length + ")");
- for (int i = 0; i < length; i++) {
- data[i] = in.readShort();
+ protected TeraDenseArray16Bit internalDeserialize(int sizeX, int sizeY, int sizeZ, ByteBuffer buffer) {
+ final int length = buffer.getInt();
+ if (length > 0) {
+ final short[] data = new short[length];
+ final ShortBuffer sbuffer = buffer.asShortBuffer();
+ sbuffer.get(data, 0, length);
+ buffer.position(buffer.position() + length * 2);
+ return new TeraDenseArray16Bit(sizeX, sizeY, sizeZ, data);
}
+ return new TeraDenseArray16Bit(sizeX, sizeY, sizeZ);
}
}
- public static class Factory implements TeraArrayFactory<TeraDenseArray16Bit> {
+ public static class Factory implements TeraArray.Factory<TeraDenseArray16Bit> {
+
@Override
public Class<TeraDenseArray16Bit> getArrayClass() {
return TeraDenseArray16Bit.class;
}
+
@Override
public TeraDenseArray16Bit create() {
return new TeraDenseArray16Bit();
}
+
@Override
public TeraDenseArray16Bit create(int sizeX, int sizeY, int sizeZ) {
return new TeraDenseArray16Bit(sizeX, sizeY, sizeZ);
View
18 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArray4Bit.java
@@ -25,21 +25,33 @@ protected final int rowSize() {
}
public static class SerializationHandler extends TeraDenseArrayByte.SerializationHandler<TeraDenseArray4Bit> {
+
@Override
- public Class<TeraDenseArray4Bit> getArrayClass() {
- return TeraDenseArray4Bit.class;
+ public boolean canHandle(Class<?> clazz) {
+ return TeraDenseArray4Bit.class.equals(clazz);
+ }
+
+ @Override
+ protected TeraDenseArray4Bit createArray(int sizeX, int sizeY, int sizeZ, byte[] data) {
+ if (data == null)
+ return new TeraDenseArray4Bit(sizeX, sizeY, sizeZ);
+ else
+ return new TeraDenseArray4Bit(sizeX, sizeY, sizeZ, data);
}
}
- public static class Factory implements TeraArrayFactory<TeraDenseArray4Bit> {
+ public static class Factory implements TeraArray.Factory<TeraDenseArray4Bit> {
+
@Override
public Class<TeraDenseArray4Bit> getArrayClass() {
return TeraDenseArray4Bit.class;
}
+
@Override
public TeraDenseArray4Bit create() {
return new TeraDenseArray4Bit();
}
+
@Override
public TeraDenseArray4Bit create(int sizeX, int sizeY, int sizeZ) {
return new TeraDenseArray4Bit(sizeX, sizeY, sizeZ);
View
18 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArray8Bit.java
@@ -25,21 +25,33 @@ protected final int rowSize() {
}
public static class SerializationHandler extends TeraDenseArrayByte.SerializationHandler<TeraDenseArray8Bit> {
+
@Override
- public Class<TeraDenseArray8Bit> getArrayClass() {
- return TeraDenseArray8Bit.class;
+ public boolean canHandle(Class<?> clazz) {
+ return TeraDenseArray8Bit.class.equals(clazz);
+ }
+
+ @Override
+ protected TeraDenseArray8Bit createArray(int sizeX, int sizeY, int sizeZ, byte[] data) {
+ if (data == null)
+ return new TeraDenseArray8Bit(sizeX, sizeY, sizeZ);
+ else
+ return new TeraDenseArray8Bit(sizeX, sizeY, sizeZ, data);
}
}
- public static class Factory implements TeraArrayFactory<TeraDenseArray8Bit> {
+ public static class Factory implements TeraArray.Factory<TeraDenseArray8Bit> {
+
@Override
public Class<TeraDenseArray8Bit> getArrayClass() {
return TeraDenseArray8Bit.class;
}
+
@Override
public TeraDenseArray8Bit create() {
return new TeraDenseArray8Bit();
}
+
@Override
public TeraDenseArray8Bit create(int sizeX, int sizeY, int sizeZ) {
return new TeraDenseArray8Bit(sizeX, sizeY, sizeZ);
View
43 src/main/java/org/terasology/world/chunks/blockdata/TeraDenseArrayByte.java
@@ -1,10 +1,9 @@
package org.terasology.world.chunks.blockdata;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
import com.google.common.base.Preconditions;
@@ -32,29 +31,39 @@ protected void initialize() {
this.data = new byte[dataSize()];
}
- protected static abstract class SerializationHandler<T extends TeraDenseArrayByte> extends TeraArray.SerializationHandler<T> {
+ protected static abstract class SerializationHandler<T extends TeraDenseArrayByte> extends TeraArray.BasicSerializationHandler<T> {
+
+ protected abstract T createArray(int sizeX, int sizeY, int sizeZ, byte[] data);
+
@Override
- protected void internalSerialize(T array, DataOutputStream out) throws IOException {
+ protected int internalComputeMinimumBufferSize(T array) {
final byte[] data = array.data;
if (data == null)
- out.writeInt(0);
+ return 4;
+ else
+ return 4 + data.length;
+ }
+
+ @Override
+ protected void internalSerialize(T array, ByteBuffer buffer) {
+ final byte[] data = array.data;
+ if (data == null)
+ buffer.putInt(0);
else {
- out.writeInt(data.length);
- for (byte b : data) {
- out.writeByte(b);
- }
+ buffer.putInt(data.length);
+ buffer.put(data);
}
}
+
@Override
- protected void internalDeserialize(T array, DataInputStream in) throws IOException {
- final byte[] data = array.data;
- final int length = in.readInt();
- Preconditions.checkNotNull(data);
- if (data.length != length)
- throw new IOException("The size of the array (" + data.length + ") does not match the size of the stored data (" + length + ")");
- for (int i = 0; i < length; i++) {
- data[i] = in.readByte();
+ protected T internalDeserialize(int sizeX, int sizeY, int sizeZ, ByteBuffer buffer) {
+ final int length = buffer.getInt();
+ if (length > 0) {
+ final byte[] data = new byte[length];
+ buffer.get(data, 0, length);
+ return createArray(sizeX, sizeY, sizeZ, data);
}
+ return createArray(sizeX, sizeY, sizeZ, null);
}
}
View
126 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArray16Bit.java
@@ -1,10 +1,10 @@
package org.terasology.world.chunks.blockdata;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
import java.util.Arrays;
import org.terasology.world.chunks.deflate.TeraVisitingDeflator;
@@ -27,80 +27,102 @@
@Override
protected void initialize() {}
+
+ public static class SerializationHandler extends TeraArray.BasicSerializationHandler<TeraSparseArray16Bit> {
- public static class SerializationHandler extends TeraArray.SerializationHandler<TeraSparseArray16Bit> {
+ private void putRow(final short[] row, final int length, final ByteBuffer buffer) {
+ final ShortBuffer sbuffer = buffer.asShortBuffer();
+ sbuffer.put(row, 0, length);
+ buffer.position(buffer.position() + length * 2);
+ }
+
+ private void getRow(final short[] row, final int length, final ByteBuffer buffer) {
+ final ShortBuffer sbuffer = buffer.asShortBuffer();
+ sbuffer.get(row, 0, length);
+ buffer.position(buffer.position() + length * 2);
+ }
+
@Override
- public Class<TeraSparseArray16Bit> getArrayClass() {
- return TeraSparseArray16Bit.class;
+ public boolean canHandle(Class<?> clazz) {
+ return TeraSparseArray16Bit.class.equals(clazz);
+ }
+
+ @Override
+ protected int internalComputeMinimumBufferSize(TeraSparseArray16Bit array) {
+ final short[][] inf = array.inflated;
+ if (inf == null)
+ return 3;
+ else {
+ final int sizeY = array.getSizeY(), rowSize = array.getSizeXZ() * 2;
+ int result = 1;
+ for (int y = 0; y < sizeY; y++)
+ if (inf[y] == null)
+ result += 3;
+ else
+ result += 1 + rowSize;
+ return result;
+ }
}
+
@Override
- protected void internalSerialize(TeraSparseArray16Bit array, DataOutputStream out) throws IOException {
- final short[][] inflated = array.inflated;
- if (inflated == null) {
- out.writeBoolean(false);
- out.writeShort(array.fill);
+ protected void internalSerialize(TeraSparseArray16Bit array, ByteBuffer buffer) {
+ final short[][] inf = array.inflated;
+ if (inf == null) {
+ buffer.put((byte) 0);
+ buffer.putShort(array.fill);
} else {
- final short[] deflated = array.deflated;
- final int sizeY = array.getSizeY();
- final int rowlen = array.getSizeXZ();
- out.writeBoolean(true);
- int rows = 0;
- for (final short[] row : inflated) {if (row != null) rows++;}
- out.writeInt(rows);
- for (int index = 0; index < sizeY; index++) {
- final short[] row = inflated[index];
+ buffer.put((byte) 1);
+ final int sizeY = array.getSizeY(), rowSize = array.getSizeXZ();
+ final short[] def = array.deflated;
+ for (int y = 0; y < sizeY; y++) {
+ final short[] row = inf[y];
if (row == null) {
- continue;
- }
- Preconditions.checkState(row.length == rowlen, "Unexpected row length in sparse array of type " + array.getClass().getName() + ", should be " + rowlen + " but is " + row.length);
- out.writeInt(index);
- for (final short b : row) {
- out.writeShort(b);
+ buffer.put((byte) 0);
+ buffer.putShort(def[y]);
+ } else {
+ buffer.put((byte) 1);
+ putRow(row, rowSize, buffer);
}
}
- for (int index = 0; index < sizeY; index++) {
- if (inflated[index] == null)
- out.writeShort(deflated[index]);
- else
- out.writeShort(0);
- }
}
}
+
@Override
- protected void internalDeserialize(TeraSparseArray16Bit array, DataInputStream in) throws IOException {
- Preconditions.checkState(array.inflated == null, "The internal array 'inflated' of type 'short[][]' is expected to be null");
- Preconditions.checkState(array.deflated == null, "The internal array 'deflated' of type 'short[]' is expected to be null");
- if (in.readBoolean()) {
- final int sizeY = array.getSizeY();
- final int rowlen = array.getSizeXZ();
- final short[][] inflated = array.inflated = new short[sizeY][];
- final int rows = in.readInt();
- for (int i = 0; i < rows; i++) {
- final int index = in.readInt();
- final short[] row = inflated[index] = new short[rowlen];
- for (int j = 0; j < rowlen; j++) {
- row[j] = in.readShort();
- }
- }
- final short[] deflated = array.deflated = new short[sizeY];
- for (int i = 0; i < sizeY; i++) {
- deflated[i] = in.readShort();
+ protected TeraSparseArray16Bit internalDeserialize(int sizeX, int sizeY, int sizeZ, ByteBuffer buffer) {
+ final byte hasData = buffer.get();
+ final TeraSparseArray16Bit array = new TeraSparseArray16Bit(sizeX, sizeY, sizeZ);
+ if (hasData == 0) {
+ array.fill = buffer.getShort();
+ return array;
+ }
+ final int rowSize = array.getSizeXZ();
+ final short[][] inf = array.inflated = new short[sizeY][];
+ final short[] def = array.deflated = new short[sizeY];
+ for (int y = 0; y < sizeY; y++) {
+ final byte hasRow = buffer.get();
+ if (hasRow == 0)
+ def[y] = buffer.getShort();
+ else {
+ final short[] row = inf[y] = new short[rowSize];
+ getRow(row, rowSize, buffer);
}
- } else {
- array.fill = in.readShort();
}
+ return array;
}
}
- public static class Factory implements TeraArrayFactory<TeraSparseArray16Bit> {
+ public static class Factory implements TeraArray.Factory<TeraSparseArray16Bit> {
+
@Override
public Class<TeraSparseArray16Bit> getArrayClass() {
return TeraSparseArray16Bit.class;
}
+
@Override
public TeraSparseArray16Bit create() {
return new TeraSparseArray16Bit();
}
+
@Override
public TeraSparseArray16Bit create(int sizeX, int sizeY, int sizeZ) {
return new TeraSparseArray16Bit(sizeX, sizeY, sizeZ);
View
17 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArray4Bit.java
@@ -71,22 +71,31 @@ private final int rowSetGetOld(byte[] row, int pos, int value) {
return old;
}
- public static class SerializationHandler extends TeraSparseArrayByte.SerializationHandler<TeraSparseArray4Bit> {
+ public static final class SerializationHandler extends TeraSparseArrayByte.SerializationHandler<TeraSparseArray4Bit> {
+
@Override
- public Class<TeraSparseArray4Bit> getArrayClass() {
- return TeraSparseArray4Bit.class;
+ public boolean canHandle(Class<?> clazz) {
+ return TeraSparseArray4Bit.class.equals(clazz);
+ }
+
+ @Override
+ protected TeraSparseArray4Bit createArray(int sizeX, int sizeY, int sizeZ) {
+ return new TeraSparseArray4Bit(sizeX, sizeY, sizeZ);
}
}
- public static class Factory implements TeraArrayFactory<TeraSparseArray4Bit> {
+ public static class Factory implements TeraArray.Factory<TeraSparseArray4Bit> {
+
@Override
public Class<TeraSparseArray4Bit> getArrayClass() {
return TeraSparseArray4Bit.class;
}
+
@Override
public TeraSparseArray4Bit create() {
return new TeraSparseArray4Bit();
}
+
@Override
public TeraSparseArray4Bit create(int sizeX, int sizeY, int sizeZ) {
return new TeraSparseArray4Bit(sizeX, sizeY, sizeZ);
View
19 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArray8Bit.java
@@ -32,22 +32,31 @@ protected final int rowSize() {
return getSizeXZ();
}
- public static class SerializationHandler extends TeraSparseArrayByte.SerializationHandler<TeraSparseArray8Bit> {
+ public static final class SerializationHandler extends TeraSparseArrayByte.SerializationHandler<TeraSparseArray8Bit> {
+
@Override
- public Class<TeraSparseArray8Bit> getArrayClass() {
- return TeraSparseArray8Bit.class;
+ public boolean canHandle(Class<?> clazz) {
+ return TeraSparseArray8Bit.class.equals(clazz);
+ }
+
+ @Override
+ protected TeraSparseArray8Bit createArray(int sizeX, int sizeY, int sizeZ) {
+ return new TeraSparseArray8Bit(sizeX, sizeY, sizeZ);
}
}
-
- public static class Factory implements TeraArrayFactory<TeraSparseArray8Bit> {
+
+ public static class Factory implements TeraArray.Factory<TeraSparseArray8Bit> {
+
@Override
public Class<TeraSparseArray8Bit> getArrayClass() {
return TeraSparseArray8Bit.class;
}
+
@Override
public TeraSparseArray8Bit create() {
return new TeraSparseArray8Bit();
}
+
@Override
public TeraSparseArray8Bit create(int sizeX, int sizeY, int sizeZ) {
return new TeraSparseArray8Bit(sizeX, sizeY, sizeZ);
View
107 src/main/java/org/terasology/world/chunks/blockdata/TeraSparseArrayByte.java
@@ -1,10 +1,9 @@
package org.terasology.world.chunks.blockdata;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
import com.google.common.base.Preconditions;
@@ -30,66 +29,74 @@
@Override
protected void initialize() {}
- protected static abstract class SerializationHandler<T extends TeraSparseArrayByte> extends TeraArray.SerializationHandler<T> {
+ protected static abstract class SerializationHandler<T extends TeraSparseArrayByte> extends TeraArray.BasicSerializationHandler<T> {
+
+ protected abstract T createArray(int sizeX, int sizeY, int sizeZ);
+
@Override
- protected void internalSerialize(T array, DataOutputStream out) throws IOException {
- final byte[][] inflated = array.inflated;
- if (inflated == null) {
- out.writeBoolean(false);
- out.writeByte(array.fill);
+ protected int internalComputeMinimumBufferSize(T array) {
+ final byte[][] inf = array.inflated;
+ if (inf == null)
+ return 2;
+ else {
+ final int sizeY = array.getSizeY(), rowSize = array.rowSize();
+ int result = 1;
+ for (int y = 0; y < sizeY; y++)
+ if (inf[y] == null)
+ result += 2;
+ else
+ result += 1 + rowSize;
+ return result;
+ }
+ }
+
+ @Override
+ protected void internalSerialize(T array, ByteBuffer buffer) {
+ final byte[][] inf = array.inflated;
+ if (inf == null) {
+ buffer.put((byte) 0);
+ buffer.put(array.fill);
} else {
- final byte[] deflated = array.deflated;
- final int sizeY = array.getSizeY();
- final int rowlen = array.rowSize();
- out.writeBoolean(true);
- int rows = 0;
- for (final byte[] row : inflated) {if (row != null) rows++;}
- out.writeInt(rows);
- for (int index = 0; index < sizeY; index++) {
- final byte[] row = inflated[index];
+ buffer.put((byte) 1);
+ final int sizeY = array.getSizeY(), rowSize = array.rowSize();
+ final byte[] def = array.deflated;
+ for (int y = 0; y < sizeY; y++) {
+ final byte[] row = inf[y];
if (row == null) {
- continue;
- }
- Preconditions.checkState(row.length == rowlen, "Unexpected row length in sparse array of type " + array.getClass().getName() + ", should be " + rowlen + " but is " + row.length);
- out.writeInt(index);
- for (final byte b : row) {
- out.writeByte(b);
+ buffer.put((byte) 0);
+ buffer.put(def[y]);
+ } else {
+ buffer.put((byte) 1);
+ buffer.put(row, 0, rowSize);
}
}
- for (int index = 0; index < sizeY; index++) {
- if (inflated[index] == null)
- out.writeByte(deflated[index]);
- else
- out.writeByte(0);
- }
}
}
+
@Override
- protected void internalDeserialize(T array, DataInputStream in) throws IOException {
- Preconditions.checkState(array.inflated == null, "The internal array 'inflated' of type 'byte[][]' is expected to be null");
- Preconditions.checkState(array.deflated == null, "The internal array 'deflated' of type 'byte[]' is expected to be null");
- if (in.readBoolean()) {
- final int sizeY = array.getSizeY();
- final int rowlen = array.rowSize();
- final byte[][] inflated = array.inflated = new byte[sizeY][];
- final int rows = in.readInt();
- for (int i = 0; i < rows; i++) {
- final int index = in.readInt();
- final byte[] row = inflated[index] = new byte[rowlen];
- for (int j = 0; j < rowlen; j++) {
- row[j] = in.readByte();
- }
- }
- final byte[] deflated = array.deflated = new byte[sizeY];
- for (int i = 0; i < sizeY; i++) {
- deflated[i] = in.readByte();
+ protected T internalDeserialize(int sizeX, int sizeY, int sizeZ, ByteBuffer buffer) {
+ final byte hasData = buffer.get();
+ final T array = createArray(sizeX, sizeY, sizeZ);
+ if (hasData == 0) {
+ array.fill = buffer.get();
+ return array;
+ }
+ final int rowSize = array.rowSize();
+ final byte[][] inf = array.inflated = new byte[sizeY][];
+ final byte[] def = array.deflated = new byte[sizeY];
+ for (int y = 0; y < sizeY; y++) {
+ final byte hasRow = buffer.get();
+ if (hasRow == 0)
+ def[y] = buffer.get();
+ else {
+ final byte[] row = inf[y] = new byte[rowSize];
+ buffer.get(row, 0, rowSize);
}
- } else {
- array.fill = in.readByte();
}
+ return array;
}
}
-
+
protected TeraSparseArrayByte() {
super();
}
View
32 src/main/protobuf/Chunks.proto
@@ -0,0 +1,32 @@
+/**
+ * Protobuf messages for TeraArrays.
+ *
+ * @author Manuel Brotz <manu.brotz@gmx.ch>
+ */
+
+option java_package = "org.terasology.protobuf";
+option java_outer_classname = "ChunksProtobuf";
+option optimize_for = SPEED;
+
+enum Type {
+ DenseArray4Bit = 1;
+ DenseArray8Bit = 2;
+ DenseArray16Bit = 3;
+ SparseArray4Bit = 4;
+ SparseArray8Bit = 5;
+ SparseArray16Bit = 6;
+}
+
+message TeraArray {
+ required Type type = 1;
+ optional bytes data = 2;
+}
+
+message Chunk {
+ optional TeraArray block = 1;
+ optional TeraArray sunlight = 2;
+ optional TeraArray light = 3;
+ optional TeraArray liquid = 4;
+
+ extensions 100 to 1000;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.