├── .gitignore ├── LICENSE.md ├── README.md ├── blixtser-benchmark ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── mojang │ └── blixtser │ └── benchmark │ ├── BlixtserSerializer.java │ ├── FastSerializer.java │ ├── JavaBuiltInSerializer.java │ ├── KryoSerializer.java │ ├── MicroBenchmark_AllModes.java │ ├── MicroBenchmark_AverageTime.java │ ├── MicroBenchmark_SampleTime.java │ ├── MicroBenchmark_SingleShotTime.java │ ├── SampleValue.java │ └── Serializer.java ├── blixtser-core ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── mojang │ │ └── blixtser │ │ └── core │ │ ├── Blixtser.java │ │ ├── ClassSchemaBuilder.java │ │ ├── SerializationUtils.java │ │ ├── TypeRepository.java │ │ ├── UnknownRegisteredHashCode.java │ │ ├── UnknownRegisteredTypeException.java │ │ └── UnsafeMemory.java │ └── test │ └── java │ └── com │ └── mojang │ └── blixtser │ └── core │ ├── BlixtserTest.java │ ├── ClassSchemaBuilderTest.java │ ├── SuperClass.java │ └── TestClasses.java ├── build.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea 3 | *.ipr 4 | *.iws 5 | .gradle 6 | /out/ 7 | .DS_Store 8 | .nb-gradle-properties 9 | fabfile.pyc 10 | /LoadTest/nbproject/private/ 11 | /LoadTest/build/ 12 | /LoadTest/dist/ 13 | FailingMco/build 14 | Frontend/out/ 15 | Common/build/ 16 | HostCollector/build/ 17 | Controller/build/ 18 | Frontend/build/ 19 | Manager/build/ 20 | TestRobot/build/ 21 | .nb-gradle/ 22 | build/ 23 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Mojang AB 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | Blixtser is a fast and efficient serialization tool for Java. The goal for this project is speed, efficiency and minimum 4 | amount of work required to use it in your production environment. 5 | 6 | ## Disclaimer 7 | 8 | Since this project is totally based on using `sun.misc.Unsafe` you should use it with care! You should be extra careful when 9 | it comes to different JVMs and architectures. As a simple example if you serialize something on machine _A_ that has 10 | different endianness and internal representation of native integer than machine _B_ that de-serializes the same thing, 11 | then you are in big trouble! 12 | 13 | ## Contents 14 | 15 | - [Quickstart](#quickstart) 16 | - [Supported Types](#supported-types) 17 | - [Benchmark](#benchmark) 18 | 19 | ## Quickstart 20 | 21 | Let's start by checking how to use the library: 22 | 23 | ```java 24 | Blixtser blixtser = new Blixtser(); 25 | blixtser.register(SomeClass.class); 26 | // ... 27 | byte[] serialized = blixtser.serialize(someclass); 28 | SomeClass deserialized = (SomeClass) blixtser.deserialize(serialized); 29 | ``` 30 | 31 | ## Supported Types 32 | 33 | Blixtser supports the following types out of the box: 34 | 35 | - `long`, `long[]`, `long[][]`, `Long` 36 | - `double`, `double[]`, `double[][]`, `Double` 37 | - `float`, `float[]`, `float[][]`, `Float` 38 | - `int`, `int[]`, `int[][]`, `Integer`, `BigInteger` 39 | - `char`, `char[]`, `char[][]`, `Character` 40 | - `short`, `short[]`, `short[][]`, `Short` 41 | - `byte`, `byte[]`, `byte[][]`, `Byte` 42 | - `boolean`, `boolean[]`, `boolean[][]`, `Boolean` 43 | - `String`, `String[]`, `String[][]`, `StringBuffer`, `StringBuilder` 44 | - `Enum` 45 | - `Date` 46 | 47 | 48 | ## Benchmark 49 | 50 | We have micro-benchmarked Blixtser against [Kryo](https://github.com/EsotericSoftware/kryo), 51 | [fast-serialization](https://code.google.com/p/fast-serialization/) and Java built-in serializer using 52 | [JMH](http://openjdk.java.net/projects/code-tools/jmh/) library. 53 | 54 | A sample micro-benchmark on a OSx 10.10 (3 GHz Intel Core i7, L2 Cache 256 KB, L3 Cache 4 MB): 55 | 56 | ``` 57 | Benchmark Mode Samples Score Error Units 58 | ----------------------------------------------------------------- 59 | blixtser thrpt 10 7,804 ? 0,711 ops/s 60 | fastSerializer thrpt 10 5,041 ? 0,233 ops/s 61 | java_built_in_serializer thrpt 10 0,324 ? 0,008 ops/s 62 | kryo thrpt 10 4,607 ? 0,311 ops/s 63 | 64 | ``` 65 | 66 | ``` 67 | Benchmark Mode Samples Score Error Units 68 | ----------------------------------------------------------------- 69 | blixtser avgt 10 0,117 ? 0,011 s/op 70 | fastSerializer avgt 10 0,208 ? 0,024 s/op 71 | java_built_in_serializer avgt 10 3,109 ? 0,129 s/op 72 | kryo avgt 10 0,261 ? 0,061 s/op 73 | ``` 74 | 75 | ``` 76 | Benchmark Mode Samples Score Error Units 77 | ----------------------------------------------------------------- 78 | blixtser sample 96 0,124 ? 0,007 s/op 79 | fastSerializer sample 56 0,224 ? 0,021 s/op 80 | java_built_in_serializer sample 10 3,649 ? 0,460 s/op 81 | kryo sample 58 0,219 ? 0,012 s/op 82 | ``` 83 | 84 | ``` 85 | Benchmark Mode Samples Score Error Units 86 | ----------------------------------------------------------------- 87 | blixtser ss 10 0,151 ? 0,058 s 88 | fastSerializer ss 10 0,284 ? 0,163 s 89 | java_built_in_serializer ss 10 3,248 ? 0,206 s 90 | kryo ss 10 0,226 ? 0,007 s 91 | ``` 92 | 93 | ### How to run the benchmarks 94 | 95 | Simply cd to `blixtser-benchmark` and run the following: 96 | 97 | ```bash 98 | $ gradle -PbenchmarkName=com.mojang.blixtser.benchmark.MicroBenchmark_AllModes benchmark 99 | ``` 100 | 101 | ## License 102 | 103 | Distributed under the [MIT License](https://github.com/Mojang/blixtser/blob/master/LICENSE.md) 104 | -------------------------------------------------------------------------------- /blixtser-benchmark/build.gradle: -------------------------------------------------------------------------------- 1 | benchmarkName = "com.mojang.blixtser.benchmark.MicroBenchmark_AllModes" 2 | 3 | dependencies { 4 | compile project(':blixtser-core') 5 | 6 | compile 'org.openjdk.jmh:jmh-core:1.1.1' 7 | compile 'org.openjdk.jmh:jmh-generator-annprocess:1.1.1' 8 | 9 | compile 'com.esotericsoftware:kryo:3.0.0' 10 | compile 'de.ruedigermoeller:fst:2.10' 11 | } 12 | 13 | task benchmark(dependsOn: classes, type:JavaExec) { 14 | main = benchmarkName; 15 | classpath = sourceSets.main.runtimeClasspath; 16 | } -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/BlixtserSerializer.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import com.mojang.blixtser.core.Blixtser; 4 | 5 | public class BlixtserSerializer implements Serializer { 6 | 7 | Blixtser blixtser = new Blixtser(); 8 | 9 | public BlixtserSerializer() { 10 | blixtser.register(SampleValue.class); 11 | } 12 | 13 | @Override 14 | public byte[] serialize(Object obj) { 15 | return blixtser.serialize(obj); 16 | } 17 | 18 | @Override 19 | public Object deserialize(byte[] arr) { 20 | return blixtser.deserialize(arr); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/FastSerializer.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | 4 | import org.nustaq.serialization.FSTConfiguration; 5 | import org.nustaq.serialization.FSTObjectInput; 6 | import org.nustaq.serialization.FSTObjectOutput; 7 | 8 | import java.io.IOException; 9 | 10 | public class FastSerializer implements Serializer { 11 | 12 | final FSTObjectOutput out; 13 | final FSTObjectInput in; 14 | 15 | byte[] buffer = new byte[4096]; 16 | 17 | { 18 | FSTConfiguration fst = FSTConfiguration.createDefaultConfiguration(); 19 | fst.setShareReferences(false); 20 | fst.setPreferSpeed(true); 21 | fst.registerClass(SampleValue.class); 22 | out = fst.getObjectOutput(buffer); 23 | in = fst.getObjectInput(buffer); 24 | } 25 | 26 | @Override 27 | public byte[] serialize(Object obj) { 28 | try { 29 | out.resetForReUse(buffer); 30 | out.writeObject(obj); 31 | return out.getBuffer(); 32 | } catch (IOException e) { 33 | throw new RuntimeException(e); 34 | } 35 | } 36 | 37 | @Override 38 | public Object deserialize(byte[] arr) { 39 | try { 40 | in.resetForReuseUseArray(arr); 41 | return in.readObject(); 42 | } catch (IOException | ClassNotFoundException e) { 43 | throw new RuntimeException(e); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/JavaBuiltInSerializer.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import java.io.*; 4 | 5 | public class JavaBuiltInSerializer implements Serializer { 6 | 7 | @Override 8 | public byte[] serialize(Object obj) { 9 | try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutput oo = new ObjectOutputStream(baos)) { 10 | oo.writeObject(obj); 11 | return baos.toByteArray(); 12 | } catch (IOException e) { 13 | throw new RuntimeException(e); 14 | } 15 | } 16 | 17 | @Override 18 | public Object deserialize(byte[] arr) { 19 | try (InputStream is = new ByteArrayInputStream(arr); ObjectInput oi = new ObjectInputStream(is)) { 20 | return oi.readObject(); 21 | } catch (IOException | ClassNotFoundException e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/KryoSerializer.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import com.esotericsoftware.kryo.Kryo; 4 | import com.esotericsoftware.kryo.io.Input; 5 | import com.esotericsoftware.kryo.io.Output; 6 | 7 | import java.nio.ByteBuffer; 8 | 9 | public class KryoSerializer implements Serializer { 10 | 11 | private Kryo kryo = new Kryo(); 12 | private ByteBuffer byteBuffer = ByteBuffer.allocate(1024); 13 | 14 | public KryoSerializer() { 15 | kryo.register(SampleValue.class); 16 | } 17 | 18 | @Override 19 | public byte[] serialize(Object obj) { 20 | byteBuffer.clear(); 21 | Output output = new Output(byteBuffer.array()); 22 | kryo.writeObject(output, obj); 23 | return byteBuffer.array(); 24 | } 25 | 26 | @Override 27 | public Object deserialize(byte[] arr) { 28 | Input input = new Input(arr); 29 | return kryo.readObject(input, SampleValue.class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/MicroBenchmark_AllModes.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | import org.openjdk.jmh.runner.Runner; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | import org.openjdk.jmh.runner.options.Options; 7 | import org.openjdk.jmh.runner.options.OptionsBuilder; 8 | 9 | import java.util.ArrayList; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | @State(Scope.Thread) 13 | public class MicroBenchmark_AllModes { 14 | 15 | private static SampleValue[] input = null; 16 | private static BlixtserSerializer blixtserSerializer = new BlixtserSerializer(); 17 | private static FastSerializer fastSerializer = new FastSerializer(); 18 | private static KryoSerializer kryoSerializer = new KryoSerializer(); 19 | private static JavaBuiltInSerializer javaBuiltInSerializer = new JavaBuiltInSerializer(); 20 | 21 | @Setup 22 | public void init() { 23 | ArrayList inputList = new ArrayList<>(); 24 | for (int i = 0; i < 550000; i++) { 25 | inputList.add(SampleValue.createRandom()); 26 | } 27 | input = inputList.toArray(new SampleValue[inputList.size()]); 28 | } 29 | 30 | @Benchmark 31 | public void kryo() { 32 | for (SampleValue anInput : input) { 33 | byte[] serialized = kryoSerializer.serialize(anInput); 34 | kryoSerializer.deserialize(serialized); 35 | } 36 | } 37 | 38 | @Benchmark 39 | public void fastSerializer() { 40 | for (SampleValue anInput : input) { 41 | byte[] serialized = fastSerializer.serialize(anInput); 42 | fastSerializer.deserialize(serialized); 43 | } 44 | } 45 | 46 | @Benchmark 47 | public void blixtser() { 48 | for (SampleValue anInput : input) { 49 | byte[] serialized = blixtserSerializer.serialize(anInput); 50 | blixtserSerializer.deserialize(serialized); 51 | } 52 | } 53 | 54 | @Benchmark 55 | public void java_built_in_serializer() { 56 | for (SampleValue anInput : input) { 57 | byte[] serialized = javaBuiltInSerializer.serialize(anInput); 58 | javaBuiltInSerializer.deserialize(serialized); 59 | } 60 | } 61 | 62 | public static void main(String[] args) throws RunnerException { 63 | Options opt = new OptionsBuilder().include(".*" + MicroBenchmark_AllModes.class.getSimpleName() + ".*") 64 | .warmupIterations(1) 65 | .measurementIterations(10) 66 | .shouldDoGC(true) 67 | .shouldFailOnError(true) 68 | .mode(Mode.All) 69 | .forks(1) 70 | .build(); 71 | new Runner(opt).run(); 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/MicroBenchmark_AverageTime.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | import org.openjdk.jmh.runner.Runner; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | import org.openjdk.jmh.runner.options.Options; 7 | import org.openjdk.jmh.runner.options.OptionsBuilder; 8 | 9 | import java.util.ArrayList; 10 | 11 | @State(Scope.Thread) 12 | public class MicroBenchmark_AverageTime { 13 | 14 | private static SampleValue[] input = null; 15 | private static BlixtserSerializer blixtserSerializer = new BlixtserSerializer(); 16 | private static FastSerializer fastSerializer = new FastSerializer(); 17 | private static KryoSerializer kryoSerializer = new KryoSerializer(); 18 | private static JavaBuiltInSerializer javaBuiltInSerializer = new JavaBuiltInSerializer(); 19 | 20 | @Setup 21 | public void init() { 22 | ArrayList inputList = new ArrayList<>(); 23 | for (int i = 0; i < 550000; i++) { 24 | inputList.add(SampleValue.createRandom()); 25 | } 26 | input = inputList.toArray(new SampleValue[inputList.size()]); 27 | } 28 | 29 | @Benchmark 30 | public void kryo() { 31 | for (SampleValue anInput : input) { 32 | byte[] serialized = kryoSerializer.serialize(anInput); 33 | kryoSerializer.deserialize(serialized); 34 | } 35 | } 36 | 37 | @Benchmark 38 | public void fastSerializer() { 39 | for (SampleValue anInput : input) { 40 | byte[] serialized = fastSerializer.serialize(anInput); 41 | fastSerializer.deserialize(serialized); 42 | } 43 | } 44 | 45 | @Benchmark 46 | public void blixtser() { 47 | for (SampleValue anInput : input) { 48 | byte[] serialized = blixtserSerializer.serialize(anInput); 49 | blixtserSerializer.deserialize(serialized); 50 | } 51 | } 52 | 53 | @Benchmark 54 | public void java_built_in_serializer() { 55 | for (SampleValue anInput : input) { 56 | byte[] serialized = javaBuiltInSerializer.serialize(anInput); 57 | javaBuiltInSerializer.deserialize(serialized); 58 | } 59 | } 60 | 61 | public static void main(String[] args) throws RunnerException { 62 | Options opt = new OptionsBuilder().include(".*" + MicroBenchmark_AverageTime.class.getSimpleName() + ".*") 63 | .warmupIterations(1) 64 | .measurementIterations(10) 65 | .shouldDoGC(true) 66 | .shouldFailOnError(true) 67 | .mode(Mode.AverageTime) 68 | .forks(1) 69 | .build(); 70 | new Runner(opt).run(); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/MicroBenchmark_SampleTime.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | import org.openjdk.jmh.runner.Runner; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | import org.openjdk.jmh.runner.options.Options; 7 | import org.openjdk.jmh.runner.options.OptionsBuilder; 8 | 9 | import java.util.ArrayList; 10 | 11 | @State(Scope.Thread) 12 | public class MicroBenchmark_SampleTime { 13 | 14 | private static SampleValue[] input = null; 15 | private static BlixtserSerializer blixtserSerializer = new BlixtserSerializer(); 16 | private static FastSerializer fastSerializer = new FastSerializer(); 17 | private static KryoSerializer kryoSerializer = new KryoSerializer(); 18 | private static JavaBuiltInSerializer javaBuiltInSerializer = new JavaBuiltInSerializer(); 19 | 20 | @Setup 21 | public void init() { 22 | ArrayList inputList = new ArrayList<>(); 23 | for (int i = 0; i < 550000; i++) { 24 | inputList.add(SampleValue.createRandom()); 25 | } 26 | input = inputList.toArray(new SampleValue[inputList.size()]); 27 | } 28 | 29 | @Benchmark 30 | public void kryo() { 31 | for (SampleValue anInput : input) { 32 | byte[] serialized = kryoSerializer.serialize(anInput); 33 | kryoSerializer.deserialize(serialized); 34 | } 35 | } 36 | 37 | @Benchmark 38 | public void fastSerializer() { 39 | for (SampleValue anInput : input) { 40 | byte[] serialized = fastSerializer.serialize(anInput); 41 | fastSerializer.deserialize(serialized); 42 | } 43 | } 44 | 45 | @Benchmark 46 | public void blixtser() { 47 | for (SampleValue anInput : input) { 48 | byte[] serialized = blixtserSerializer.serialize(anInput); 49 | blixtserSerializer.deserialize(serialized); 50 | } 51 | } 52 | 53 | @Benchmark 54 | public void java_built_in_serializer() { 55 | for (SampleValue anInput : input) { 56 | byte[] serialized = javaBuiltInSerializer.serialize(anInput); 57 | javaBuiltInSerializer.deserialize(serialized); 58 | } 59 | } 60 | 61 | public static void main(String[] args) throws RunnerException { 62 | Options opt = new OptionsBuilder().include(".*" + MicroBenchmark_SampleTime.class.getSimpleName() + ".*") 63 | .warmupIterations(1) 64 | .measurementIterations(10) 65 | .shouldDoGC(true) 66 | .shouldFailOnError(true) 67 | .mode(Mode.SampleTime) 68 | .forks(1) 69 | .build(); 70 | new Runner(opt).run(); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/MicroBenchmark_SingleShotTime.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | import org.openjdk.jmh.runner.Runner; 5 | import org.openjdk.jmh.runner.RunnerException; 6 | import org.openjdk.jmh.runner.options.Options; 7 | import org.openjdk.jmh.runner.options.OptionsBuilder; 8 | 9 | import java.util.ArrayList; 10 | 11 | @State(Scope.Thread) 12 | public class MicroBenchmark_SingleShotTime { 13 | 14 | private static SampleValue[] input = null; 15 | private static BlixtserSerializer blixtserSerializer = new BlixtserSerializer(); 16 | private static FastSerializer fastSerializer = new FastSerializer(); 17 | private static KryoSerializer kryoSerializer = new KryoSerializer(); 18 | private static JavaBuiltInSerializer javaBuiltInSerializer = new JavaBuiltInSerializer(); 19 | 20 | @Setup 21 | public void init() { 22 | ArrayList inputList = new ArrayList<>(); 23 | for (int i = 0; i < 550000; i++) { 24 | inputList.add(SampleValue.createRandom()); 25 | } 26 | input = inputList.toArray(new SampleValue[inputList.size()]); 27 | } 28 | 29 | @Benchmark 30 | public void kryo() { 31 | for (SampleValue anInput : input) { 32 | byte[] serialized = kryoSerializer.serialize(anInput); 33 | kryoSerializer.deserialize(serialized); 34 | } 35 | } 36 | 37 | @Benchmark 38 | public void fastSerializer() { 39 | for (SampleValue anInput : input) { 40 | byte[] serialized = fastSerializer.serialize(anInput); 41 | fastSerializer.deserialize(serialized); 42 | } 43 | } 44 | 45 | @Benchmark 46 | public void blixtser() { 47 | for (SampleValue anInput : input) { 48 | byte[] serialized = blixtserSerializer.serialize(anInput); 49 | blixtserSerializer.deserialize(serialized); 50 | } 51 | } 52 | 53 | @Benchmark 54 | public void java_built_in_serializer() { 55 | for (SampleValue anInput : input) { 56 | byte[] serialized = javaBuiltInSerializer.serialize(anInput); 57 | javaBuiltInSerializer.deserialize(serialized); 58 | } 59 | } 60 | 61 | public static void main(String[] args) throws RunnerException { 62 | Options opt = new OptionsBuilder().include(".*" + MicroBenchmark_SingleShotTime.class.getSimpleName() + ".*") 63 | .warmupIterations(1) 64 | .measurementIterations(10) 65 | .shouldDoGC(true) 66 | .shouldFailOnError(true) 67 | .mode(Mode.SingleShotTime) 68 | .forks(1) 69 | .build(); 70 | new Runner(opt).run(); 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /blixtser-benchmark/src/main/java/com/mojang/blixtser/benchmark/SampleValue.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.benchmark; 2 | 3 | import java.io.Serializable; 4 | import java.lang.String; 5 | import java.util.Objects; 6 | import java.util.Random; 7 | import java.util.UUID; 8 | 9 | public class SampleValue implements Serializable { 10 | 11 | String aString; 12 | volatile int aInt; 13 | long aWrappedLong; 14 | byte aByte; 15 | /* 16 | String[] strings; 17 | */ 18 | 19 | private final static Random rnd = new Random(); 20 | 21 | private SampleValue() { 22 | } 23 | 24 | public static SampleValue createRandom() { 25 | SampleValue val = new SampleValue(); 26 | val.aString = UUID.randomUUID().toString(); 27 | val.aInt = rnd.nextInt(); 28 | val.aWrappedLong = rnd.nextLong(); 29 | val.aByte = 2; 30 | /* 31 | val.strings = new String[2]; 32 | for (int i=0; i 5 | * A super unsafeSerializer should support: 6 | * - all kinds of value objects as below 7 | * - fields of all visibility 8 | * - transient fields should be excluded from the serialized state 9 | * - value objects may with any constructors 10 | * - members of primitives, wrapped primitives and Strings 11 | * - arrays of types above is optional but gives bonus points :-) 12 | * 13 | * Does not have to support: 14 | * - inheritance for value objects 15 | * - final fields 16 | * - member objects other than those mentioned above 17 | * 18 | */ 19 | public interface Serializer { 20 | 21 | public byte[] serialize(Object obj); 22 | 23 | public Object deserialize(byte[] arr); 24 | } 25 | -------------------------------------------------------------------------------- /blixtser-core/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testCompile 'junit:junit:4.11' 3 | testCompile 'org.projectlombok:lombok:1.12.2' 4 | } -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/Blixtser.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import com.mojang.blixtser.core.ClassSchemaBuilder.ClassInfo; 4 | import com.mojang.blixtser.core.ClassSchemaBuilder.FieldInfo; 5 | import java.io.*; 6 | import java.util.HashSet; 7 | 8 | import static com.mojang.blixtser.core.ClassSchemaBuilder.classInfoCache; 9 | 10 | @SuppressWarnings("all") 11 | public class Blixtser { 12 | 13 | private final UnsafeMemory unsafeMemory = new UnsafeMemory(); 14 | private final ClassSchemaBuilder classSchemaBuilder = new ClassSchemaBuilder(); 15 | 16 | private FieldInfo[] fieldInfos; 17 | private int code = Integer.MIN_VALUE; 18 | 19 | public void register(Class c) { 20 | classSchemaBuilder.registerClass(c, new HashSet()); 21 | } 22 | 23 | public byte[] serialize(Object obj) { 24 | unsafeMemory.reset(); 25 | 26 | Class cl = obj.getClass(); 27 | int c = cl.hashCode(); 28 | 29 | if (code != c) { 30 | if (!classInfoCache.containsKey(c)) { 31 | throw new UnknownRegisteredTypeException(obj.getClass().getName()); 32 | } 33 | fieldInfos = classInfoCache.get(c).fieldInfos; 34 | } 35 | 36 | unsafeMemory.writeInt(c); 37 | for (FieldInfo f : fieldInfos) { 38 | f.serialize(unsafeMemory, obj); 39 | } 40 | 41 | return unsafeMemory.getBuffer(); 42 | } 43 | 44 | public Object deserialize(byte[] data) { 45 | UnsafeMemory unsafeMemory = new UnsafeMemory(data); 46 | 47 | int c = unsafeMemory.readInt(); 48 | ClassInfo classInfo = classInfoCache.get(c); 49 | try { 50 | Object obj = classInfo.instance(); 51 | 52 | for (FieldInfo f : classInfo.fieldInfos) { 53 | f.deserialize(unsafeMemory, obj); 54 | } 55 | 56 | return obj; 57 | } catch (Exception e) { 58 | throw new RuntimeException(e); 59 | } 60 | } 61 | 62 | public void writeObject(Object obj, OutputStream out) throws IOException { 63 | byte[] data = serialize(obj); 64 | int size = data.length; 65 | 66 | out.write((size >>> 24) & 0xFF); 67 | out.write((size >>> 16) & 0xFF); 68 | out.write((size >>> 8) & 0xFF); 69 | out.write(size & 0xFF); 70 | out.write(data); 71 | } 72 | 73 | public Object readObject(InputStream in) throws IOException { 74 | int b3 = in.read(); 75 | int b2 = in.read(); 76 | int b1 = in.read(); 77 | int b0 = in.read(); 78 | if ((b3 | b2 | b1 | b0) < 0) { 79 | throw new EOFException(); 80 | } 81 | 82 | int size = (b3 << 24) + (b2 << 16) + (b1 << 8) + b0; 83 | byte[] data = new byte[size]; 84 | 85 | for (int i = 0; i < size; i++) { 86 | int d = in.read(); 87 | if (d < 0) { 88 | throw new EOFException("Couldn't read object from InputStream, EOF"); 89 | } 90 | data[i] = (byte) d; 91 | } 92 | 93 | return deserialize(data); 94 | } 95 | 96 | /** 97 | * 98 | */ 99 | } 100 | -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/ClassSchemaBuilder.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Modifier; 5 | import java.math.BigInteger; 6 | import java.util.*; 7 | 8 | import static com.mojang.blixtser.core.TypeRepository.*; 9 | 10 | class ClassSchemaBuilder { 11 | 12 | static final Map classInfoCache = new HashMap<>(); 13 | 14 | static ClassInfo stringClassInfo; 15 | static ClassInfo stringBufferInfo; 16 | static ClassInfo stringBuilderInfo; 17 | static ClassInfo bigIntegerClassInfo; 18 | static ClassInfo dateClassInfo; 19 | 20 | ClassSchemaBuilder() { 21 | Set ignoreFields = new HashSet<>(); 22 | ignoreFields.add("hash"); 23 | 24 | stringClassInfo = createClassInfo(String.class, ignoreFields, false); 25 | stringBufferInfo = createClassInfo(StringBuffer.class); 26 | stringBuilderInfo = createClassInfo(StringBuilder.class); 27 | bigIntegerClassInfo = createClassInfo(BigInteger.class); 28 | 29 | ignoreFields.clear(); 30 | ignoreFields.add("cdate"); 31 | dateClassInfo = createClassInfo(Date.class, ignoreFields, true); 32 | } 33 | 34 | void registerClass(Class c, Set ignoreFields) { 35 | registerClass(c, ignoreFields, false); 36 | } 37 | 38 | ClassInfo createClassInfo(Class c) { 39 | return createClassInfo(c, Collections.emptySet(), false); 40 | } 41 | 42 | void registerClass(Class c, Set ignoreFields, boolean withTransient) { 43 | ClassInfo classInfo = classInfoCache.get(c); 44 | if (classInfo == null) { 45 | valiadateClass(c); 46 | classInfo = createClassInfo(c, ignoreFields, withTransient); 47 | int code = c.hashCode(); 48 | classInfoCache.put(code, classInfo); 49 | } 50 | } 51 | 52 | ClassInfo createClassInfo(Class c, Set fieldNamesToIgnore, boolean withTransient) { 53 | ClassInfo classInfo = classInfoCache.get(c); 54 | if (classInfo == null) { 55 | valiadateClass(c); 56 | List fields = getFieldsFor(c, fieldNamesToIgnore, withTransient); 57 | List fieldsWithInfo = mapFieldsToFieldInfo(fields); 58 | FieldInfo[] fieldInfos = fieldsWithInfo.toArray(new FieldInfo[fieldsWithInfo.size()]); 59 | sortFieldOnOffset(fieldInfos); 60 | fieldInfos = mergeNonVolatilePrimitiveFields(fieldInfos); 61 | classInfo = new ClassInfo(c, fieldInfos); 62 | } 63 | return classInfo; 64 | } 65 | 66 | private void valiadateClass(Class c) { 67 | if (Modifier.isAbstract(c.getModifiers()) || Modifier.isInterface(c.getModifiers())) { 68 | throw new RuntimeException("Can not register an abstract class"); 69 | } 70 | 71 | if (Modifier.isInterface(c.getModifiers())) { 72 | throw new RuntimeException("Can not register an interface class"); 73 | } 74 | } 75 | 76 | private List mapFieldsToFieldInfo(List fields) { 77 | List fieldsWithInfo = new ArrayList<>(fields.size()); 78 | for (Field field : fields) { 79 | FieldInfo fi = createFieldInfo(field); 80 | if (fi != null) { 81 | fieldsWithInfo.add(fi); 82 | } 83 | } 84 | return fieldsWithInfo; 85 | } 86 | 87 | private FieldInfo createFieldInfo(Field field) { 88 | if (Modifier.isVolatile(field.getModifiers())) { 89 | return createVolatileField(field); 90 | } else { 91 | return createNonVolatileField(field); 92 | } 93 | } 94 | 95 | private FieldInfo createNonVolatileField(Field field) { 96 | if (nonVolatileTypeRepository.serializerDeserializerExistsFor(field.getType())) { 97 | return new FieldInfo(field, nonVolatileTypeRepository.getSerializer(field.getType()), 98 | nonVolatileTypeRepository.getDeserializer(field.getType())); 99 | } else if (field.getType().getSuperclass() == Enum.class) { 100 | return new EnumFieldInfo(field, nonVolatileTypeRepository.getSerializer(Enum.class)); 101 | } else { 102 | System.out.println("Unsupported declared field " + field.getName() + "[" + field.getType().getName() + "] in Class " + field.getDeclaringClass().getName() + ", skipping..."); 103 | return null; 104 | } 105 | } 106 | 107 | private FieldInfo createVolatileField(Field field) { 108 | if (volatileTypeRepository.serializerDeserializerExistsFor(field.getType())) { 109 | return new FieldInfo(field, volatileTypeRepository.getSerializer(field.getType()), volatileTypeRepository.getDeserializer(field.getType())); 110 | } else if (field.getType().getSuperclass() == Enum.class) { 111 | return new EnumVolatileFieldInfo(field, volatileTypeRepository.getSerializer(Enum.class)); 112 | } else { 113 | System.out.println("Unsupported declared field " + field.getName() + "[" + field.getType().getName() + "] in Class " + field.getDeclaringClass().getName() + ", skipping..."); 114 | return null; 115 | } 116 | } 117 | 118 | private void sortFieldOnOffset(FieldInfo[] infos) { 119 | Arrays.sort(infos, new Comparator() { 120 | @Override 121 | public int compare(FieldInfo o1, FieldInfo o2) { 122 | return (int) (o1.offset - o2.offset); 123 | } 124 | }); 125 | } 126 | 127 | private List getFieldsFor(Class c, Set ignoreFields, boolean withTransient) { 128 | List fields = new ArrayList<>(); 129 | List ffs = getAllFieldsRecursiveFor(c); 130 | for (Field f : ffs) { 131 | if (ignoreFields.contains(f.getName())) { 132 | continue; 133 | } 134 | if ((f.getModifiers() & Modifier.STATIC) == 0) { 135 | if (withTransient || (f.getModifiers() & Modifier.TRANSIENT) == 0) { 136 | fields.add(f); 137 | } 138 | } 139 | } 140 | return fields; 141 | } 142 | 143 | private List getAllFieldsRecursiveFor(Class c) { 144 | if (c == Object.class) { 145 | return new ArrayList<>(); 146 | } 147 | List allFields = getAllFieldsRecursiveFor(c.getSuperclass()); 148 | allFields.addAll(Arrays.asList(c.getDeclaredFields())); 149 | return allFields; 150 | } 151 | 152 | private FieldInfo[] mergeNonVolatilePrimitiveFields(FieldInfo[] fields) { 153 | if (fields.length <= 1) { 154 | return fields; 155 | } 156 | 157 | List mergingResult = new ArrayList<>(); 158 | mergingResult.add(fields[0]); 159 | for (int i = 1; i < fields.length; i++) { 160 | FieldInfo previousField = mergingResult.get(mergingResult.size() - 1); 161 | FieldInfo currentField = fields[i]; 162 | 163 | if (isNonVolatilePrimitive(previousField) && isNonVolatilePrimitive(currentField)) { 164 | BatchFieldInfo batchField = previousField.merge(currentField); 165 | mergingResult.set(mergingResult.size() - 1, batchField); 166 | } else { 167 | mergingResult.add(currentField); 168 | } 169 | } 170 | 171 | return mergingResult.toArray(new FieldInfo[mergingResult.size()]); 172 | } 173 | 174 | private boolean isNonVolatilePrimitive(FieldInfo fieldInfo) { 175 | return fieldInfo.type().isPrimitive() && 176 | !Modifier.isVolatile(fieldInfo.field.getModifiers()); 177 | } 178 | 179 | /** 180 | * 181 | */ 182 | static class FieldInfo { 183 | 184 | protected SerializationUtils.Serializer fieldSerializer; 185 | protected SerializationUtils.Deserializer fieldDeserializer; 186 | protected final Field field; 187 | protected long offset; 188 | 189 | FieldInfo(Field field, SerializationUtils.Serializer fieldSerializer, SerializationUtils.Deserializer fieldDeserializer) { 190 | this.field = field; 191 | this.fieldSerializer = fieldSerializer; 192 | this.fieldDeserializer = fieldDeserializer; 193 | this.offset = SerializationUtils.unsafe.objectFieldOffset(field); 194 | } 195 | 196 | void serialize(UnsafeMemory unsafeMemory, Object object) { 197 | fieldSerializer.serialize(unsafeMemory, object, offset); 198 | } 199 | 200 | void deserialize(UnsafeMemory unsafeMemory, Object object) { 201 | fieldDeserializer.deserialize(unsafeMemory, object, offset); 202 | } 203 | 204 | Class type() { 205 | return field.getType(); 206 | } 207 | 208 | public BatchFieldInfo merge(FieldInfo fieldInfo) { 209 | int size = (int) (fieldInfo.offset - this.offset + sizeOf(fieldInfo.type())); 210 | return new BatchFieldInfo(this, size); 211 | } 212 | 213 | @Override 214 | public String toString() { 215 | return "FieldInfo{" + 216 | "offset=" + offset + 217 | ", name=" + field.getName() + 218 | ", type=" + field.getType() + 219 | '}'; 220 | } 221 | } 222 | 223 | /** 224 | * 225 | */ 226 | final static class BatchFieldInfo extends FieldInfo { 227 | 228 | private final FieldInfo firstField; 229 | 230 | BatchFieldInfo(FieldInfo firstField, int size) { 231 | super(firstField.field, new SerializationUtils.BatchSerializer(size), new SerializationUtils.BatchDeserializer(size)); 232 | this.firstField = firstField; 233 | } 234 | 235 | public BatchFieldInfo merge(FieldInfo fieldInfo) { 236 | int size = (int) (fieldInfo.offset - this.offset + sizeOf(fieldInfo.type())); 237 | return new BatchFieldInfo(firstField, size); 238 | } 239 | 240 | } 241 | 242 | /** 243 | * 244 | */ 245 | static class EnumFieldInfo extends FieldInfo { 246 | 247 | protected Field ordinalField; 248 | protected long ordinalOffset; 249 | protected Field valuesField; 250 | protected long valuesOffset; 251 | 252 | EnumFieldInfo(Field field, SerializationUtils.Serializer fieldSerializer) { 253 | super(field, fieldSerializer, null); 254 | offset = SerializationUtils.unsafe.objectFieldOffset(field); 255 | getOrdinalField(); 256 | } 257 | 258 | private void getOrdinalField() { 259 | try { 260 | ordinalField = field.getType().getSuperclass().getDeclaredField("ordinal"); 261 | valuesField = field.getType().getDeclaredField("$VALUES"); 262 | } catch (NoSuchFieldException e) { 263 | throw new RuntimeException("Failed to get field from Enum Class:" + e.getMessage()); 264 | } 265 | 266 | ordinalOffset = SerializationUtils.unsafe.objectFieldOffset(ordinalField); 267 | valuesOffset = SerializationUtils.unsafe.staticFieldOffset(valuesField); 268 | } 269 | 270 | void serialize(UnsafeMemory unsafeMemory, Object object) { 271 | Object enumReference = SerializationUtils.unsafe.getObject(object, offset); 272 | fieldSerializer.serialize(unsafeMemory, enumReference, ordinalOffset); 273 | } 274 | 275 | void deserialize(UnsafeMemory unsafeMemory, Object object) { 276 | Object[] values = (Object[]) SerializationUtils.unsafe.getObject(field.getType(), valuesOffset); 277 | int ordinal = unsafeMemory.readInt(); 278 | SerializationUtils.unsafe.putObject(object, offset, values[ordinal]); 279 | } 280 | } 281 | 282 | /** 283 | * 284 | */ 285 | final static class EnumVolatileFieldInfo extends EnumFieldInfo { 286 | 287 | EnumVolatileFieldInfo(Field field, SerializationUtils.Serializer fieldSerializer) { 288 | super(field, fieldSerializer); 289 | } 290 | 291 | void serialize(UnsafeMemory unsafeMemory, Object object) { 292 | Object enumReference = SerializationUtils.unsafe.getObjectVolatile(object, offset); 293 | fieldSerializer.serialize(unsafeMemory, enumReference, ordinalOffset); 294 | } 295 | 296 | void deserialize(UnsafeMemory unsafeMemory, Object object) { 297 | Object[] values = (Object[]) SerializationUtils.unsafe.getObject(field.getType(), valuesOffset); 298 | int ordinal = unsafeMemory.readInt(); 299 | SerializationUtils.unsafe.putObjectVolatile(object, offset, values[ordinal]); 300 | } 301 | } 302 | 303 | /** 304 | * 305 | */ 306 | final static class ClassInfo { 307 | final Class clazz; 308 | final FieldInfo[] fieldInfos; 309 | 310 | ClassInfo(Class clazz, FieldInfo[] fieldInfos) { 311 | this.clazz = clazz; 312 | this.fieldInfos = fieldInfos; 313 | } 314 | 315 | Object instance() throws InstantiationException { 316 | return SerializationUtils.unsafe.allocateInstance(clazz); 317 | } 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/SerializationUtils.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import sun.misc.Unsafe; 4 | 5 | import java.lang.reflect.Field; 6 | 7 | import static com.mojang.blixtser.core.ClassSchemaBuilder.*; 8 | 9 | class SerializationUtils { 10 | 11 | public static Unsafe unsafe = getUnsafeInstance(); 12 | 13 | private static Unsafe getUnsafeInstance() { 14 | try { 15 | Field f = Unsafe.class.getDeclaredField("theUnsafe"); 16 | f.setAccessible(true); 17 | return (Unsafe) f.get(null); 18 | } catch (ReflectiveOperationException e) { 19 | throw new RuntimeException(e); 20 | } 21 | } 22 | 23 | private static boolean writeNullableObject(UnsafeMemory unsafeMemory, Object object) { 24 | if (object == null) { 25 | unsafeMemory.writeByte((byte) 0); 26 | return true; 27 | } else { 28 | unsafeMemory.writeByte((byte) 1); 29 | return false; 30 | } 31 | } 32 | 33 | private static boolean readNullableObject(UnsafeMemory unsafeMemory) { 34 | return unsafeMemory.readByte() == 0; 35 | } 36 | 37 | private static void serializeObject(ClassInfo classInfo, UnsafeMemory unsafeMemory, Object object, long offset) { 38 | Object serializedObject = unsafe.getObject(object, offset); 39 | if (!writeNullableObject(unsafeMemory, serializedObject)) { 40 | for (FieldInfo f : classInfo.fieldInfos) { 41 | f.serialize(unsafeMemory, serializedObject); 42 | } 43 | } 44 | } 45 | 46 | private static void serializeVolatileObject(ClassInfo classInfo, UnsafeMemory unsafeMemory, Object object, long offset) { 47 | Object serializedObject = unsafe.getObjectVolatile(object, offset); 48 | if (!writeNullableObject(unsafeMemory, serializedObject)) { 49 | for (FieldInfo f : classInfo.fieldInfos) { 50 | f.serialize(unsafeMemory, serializedObject); 51 | } 52 | } 53 | } 54 | 55 | private static void deserializeObject(ClassInfo classInfo, UnsafeMemory unsafeMemory, Object object, long offset) { 56 | try { 57 | Object deserializedObject = null; 58 | if (!readNullableObject(unsafeMemory)) { 59 | deserializedObject = unsafe.allocateInstance(classInfo.clazz); 60 | for (FieldInfo f : classInfo.fieldInfos) { 61 | f.deserialize(unsafeMemory, deserializedObject); 62 | } 63 | } 64 | unsafe.putObject(object, offset, deserializedObject); 65 | } catch (InstantiationException e) { 66 | throw new RuntimeException("Failed to deserialize " + classInfo.clazz + ": " + e); 67 | } 68 | } 69 | 70 | private static void deserializeVolatileObject(ClassInfo classInfo, UnsafeMemory unsafeMemory, Object object, long offset) { 71 | try { 72 | Object deserializedObject = null; 73 | if (!readNullableObject(unsafeMemory)) { 74 | deserializedObject = unsafe.allocateInstance(classInfo.clazz); 75 | for (FieldInfo f : classInfo.fieldInfos) { 76 | f.deserialize(unsafeMemory, deserializedObject); 77 | } 78 | } 79 | unsafe.putObjectVolatile(object, offset, deserializedObject); 80 | } catch (InstantiationException e) { 81 | throw new RuntimeException("Failed to deserialize " + classInfo.clazz + ": " + e); 82 | } 83 | } 84 | 85 | 86 | static interface Serializer { 87 | 88 | void serialize(UnsafeMemory unsafeMemory, Object object, long offset); 89 | 90 | } 91 | 92 | static interface Deserializer { 93 | 94 | void deserialize(UnsafeMemory unsafeMemory, Object object, long offset); 95 | 96 | } 97 | 98 | static class IntSerializer implements Serializer { 99 | @Override 100 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 101 | unsafeMemory.writeInt(unsafe.getInt(object, offset)); 102 | } 103 | } 104 | 105 | static class IntVolatileSerializer implements Serializer { 106 | @Override 107 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 108 | unsafeMemory.writeInt(unsafe.getIntVolatile(object, offset)); 109 | } 110 | } 111 | 112 | static class IntDeserializer implements Deserializer { 113 | @Override 114 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 115 | unsafe.putInt(object, offset, unsafeMemory.readInt()); 116 | } 117 | } 118 | 119 | static class IntVolatileDeserializer implements Deserializer { 120 | @Override 121 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 122 | unsafe.putIntVolatile(object, offset, unsafeMemory.readInt()); 123 | } 124 | } 125 | 126 | static class LongSerializer implements Serializer { 127 | @Override 128 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 129 | unsafeMemory.writeLong(unsafe.getLong(object, offset)); 130 | } 131 | } 132 | 133 | static class LongVolatileSerializer implements Serializer { 134 | @Override 135 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 136 | unsafeMemory.writeLong(unsafe.getLongVolatile(object, offset)); 137 | } 138 | } 139 | 140 | static class LongDeserializer implements Deserializer { 141 | @Override 142 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 143 | unsafe.putLong(object, offset, unsafeMemory.readLong()); 144 | } 145 | } 146 | 147 | static class LongVolatileDeserializer implements Deserializer { 148 | @Override 149 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 150 | unsafe.putLongVolatile(object, offset, unsafeMemory.readLong()); 151 | } 152 | } 153 | 154 | static class ShortSerializer implements Serializer { 155 | @Override 156 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 157 | unsafeMemory.writeShort(unsafe.getShort(object, offset)); 158 | } 159 | } 160 | 161 | static class ShortVolatileSerializer implements Serializer { 162 | @Override 163 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 164 | unsafeMemory.writeShort(unsafe.getShortVolatile(object, offset)); 165 | } 166 | } 167 | 168 | static class ShortDeserializer implements Deserializer { 169 | @Override 170 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 171 | unsafe.putShort(object, offset, unsafeMemory.readShort()); 172 | } 173 | } 174 | 175 | static class ShortVolatileDeserializer implements Deserializer { 176 | @Override 177 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 178 | unsafe.putShortVolatile(object, offset, unsafeMemory.readShort()); 179 | } 180 | } 181 | 182 | static class DoubleSerializer implements Serializer { 183 | @Override 184 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 185 | unsafeMemory.writeDouble(unsafe.getDouble(object, offset)); 186 | } 187 | } 188 | 189 | static class DoubleVolatileSerializer implements Serializer { 190 | @Override 191 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 192 | unsafeMemory.writeDouble(unsafe.getDoubleVolatile(object, offset)); 193 | } 194 | } 195 | 196 | static class DoubleDeserializer implements Deserializer { 197 | @Override 198 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 199 | unsafe.putDouble(object, offset, unsafeMemory.readDouble()); 200 | } 201 | } 202 | 203 | static class DoubleVolatileDeserializer implements Deserializer { 204 | @Override 205 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 206 | unsafe.putDoubleVolatile(object, offset, unsafeMemory.readDouble()); 207 | } 208 | } 209 | 210 | static class FloatSerializer implements Serializer { 211 | @Override 212 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 213 | unsafeMemory.writeFloat(unsafe.getFloat(object, offset)); 214 | } 215 | } 216 | 217 | static class FloatVolatileSerializer implements Serializer { 218 | @Override 219 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 220 | unsafeMemory.writeFloat(unsafe.getFloatVolatile(object, offset)); 221 | } 222 | } 223 | 224 | static class FloatDeserializer implements Deserializer { 225 | @Override 226 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 227 | unsafe.putFloat(object, offset, unsafeMemory.readFloat()); 228 | } 229 | } 230 | 231 | static class FloatVolatileDeserializer implements Deserializer { 232 | @Override 233 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 234 | unsafe.putFloatVolatile(object, offset, unsafeMemory.readFloat()); 235 | } 236 | } 237 | 238 | static class ByteSerializer implements Serializer { 239 | @Override 240 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 241 | unsafeMemory.writeByte(unsafe.getByte(object, offset)); 242 | } 243 | } 244 | 245 | static class ByteVolatileSerializer implements Serializer { 246 | @Override 247 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 248 | unsafeMemory.writeByte(unsafe.getByteVolatile(object, offset)); 249 | } 250 | } 251 | 252 | static class ByteDeserializer implements Deserializer { 253 | @Override 254 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 255 | unsafe.putByte(object, offset, unsafeMemory.readByte()); 256 | } 257 | } 258 | 259 | static class ByteVolatileDeserializer implements Deserializer { 260 | @Override 261 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 262 | unsafe.putByteVolatile(object, offset, unsafeMemory.readByte()); 263 | } 264 | } 265 | 266 | static class BooleanSerializer implements Serializer { 267 | @Override 268 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 269 | unsafeMemory.writeBoolean(unsafe.getBoolean(object, offset)); 270 | } 271 | } 272 | 273 | static class BooleanVolatileSerializer implements Serializer { 274 | @Override 275 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 276 | unsafeMemory.writeBoolean(unsafe.getBooleanVolatile(object, offset)); 277 | } 278 | } 279 | 280 | static class BooleanDeserializer implements Deserializer { 281 | @Override 282 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 283 | unsafe.putBoolean(object, offset, unsafeMemory.readBoolean()); 284 | } 285 | } 286 | 287 | static class BooleanVolatileDeserializer implements Deserializer { 288 | @Override 289 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 290 | unsafe.putBooleanVolatile(object, offset, unsafeMemory.readBoolean()); 291 | } 292 | } 293 | 294 | static class CharSerializer implements Serializer { 295 | @Override 296 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 297 | unsafeMemory.writeChar(unsafe.getChar(object, offset)); 298 | } 299 | } 300 | 301 | static class CharVolatileSerializer implements Serializer { 302 | @Override 303 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 304 | unsafeMemory.writeChar(unsafe.getCharVolatile(object, offset)); 305 | } 306 | } 307 | 308 | static class CharDeserializer implements Deserializer { 309 | @Override 310 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 311 | unsafe.putChar(object, offset, unsafeMemory.readChar()); 312 | } 313 | } 314 | 315 | static class CharVolatileDeserializer implements Deserializer { 316 | @Override 317 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 318 | unsafe.putCharVolatile(object, offset, unsafeMemory.readChar()); 319 | } 320 | } 321 | 322 | static class DateSerializer implements Serializer { 323 | @Override 324 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 325 | serializeObject(dateClassInfo, unsafeMemory, object, offset); 326 | } 327 | } 328 | 329 | static class StringSerializer implements Serializer { 330 | @Override 331 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 332 | serializeObject(stringClassInfo, unsafeMemory, object, offset); 333 | } 334 | } 335 | 336 | static class StringVolatileSerializer implements Serializer { 337 | @Override 338 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 339 | serializeVolatileObject(stringClassInfo, unsafeMemory, object, offset); 340 | } 341 | } 342 | 343 | static class StringDeserializer implements Deserializer { 344 | @Override 345 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 346 | deserializeObject(stringClassInfo, unsafeMemory, object, offset); 347 | } 348 | } 349 | 350 | static class DateDeserializer implements Deserializer { 351 | @Override 352 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 353 | deserializeObject(dateClassInfo, unsafeMemory, object, offset); 354 | } 355 | } 356 | 357 | static class StringVolatileDeserializer implements Deserializer { 358 | @Override 359 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 360 | deserializeVolatileObject(stringClassInfo, unsafeMemory, object, offset); 361 | } 362 | } 363 | 364 | static class StringBufferSerializer implements Serializer { 365 | @Override 366 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 367 | serializeObject(stringBufferInfo, unsafeMemory, object, offset); 368 | } 369 | } 370 | 371 | static class StringBufferVolatileSerializer implements Serializer { 372 | @Override 373 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 374 | serializeVolatileObject(stringBufferInfo, unsafeMemory, object, offset); 375 | } 376 | } 377 | 378 | static class StringBufferDeserializer implements Deserializer { 379 | @Override 380 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 381 | deserializeObject(stringBufferInfo, unsafeMemory, object, offset); 382 | } 383 | } 384 | 385 | static class StringBufferVolatileDeserializer implements Deserializer { 386 | @Override 387 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 388 | deserializeVolatileObject(stringBufferInfo, unsafeMemory, object, offset); 389 | } 390 | } 391 | 392 | static class StringBuilderSerializer implements Serializer { 393 | @Override 394 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 395 | serializeObject(stringBuilderInfo, unsafeMemory, object, offset); 396 | } 397 | } 398 | 399 | static class StringBuilderVolatileSerializer implements Serializer { 400 | @Override 401 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 402 | serializeVolatileObject(stringBuilderInfo, unsafeMemory, object, offset); 403 | } 404 | } 405 | 406 | static class StringBuilderDeserializer implements Deserializer { 407 | @Override 408 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 409 | deserializeObject(stringBuilderInfo, unsafeMemory, object, offset); 410 | } 411 | } 412 | 413 | static class StringBuilderVolatileDeserializer implements Deserializer { 414 | @Override 415 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 416 | deserializeVolatileObject(stringBuilderInfo, unsafeMemory, object, offset); 417 | } 418 | } 419 | 420 | static class IntegerSerializer implements Serializer { 421 | @Override 422 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 423 | unsafeMemory.writeInteger((Integer) unsafe.getObject(object, offset)); 424 | } 425 | } 426 | 427 | static class IntegerVolatileSerializer implements Serializer { 428 | @Override 429 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 430 | unsafeMemory.writeInteger((Integer) unsafe.getObjectVolatile(object, offset)); 431 | } 432 | } 433 | 434 | static class IntegerDeserializer implements Deserializer { 435 | @Override 436 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 437 | unsafe.putObject(object, offset, unsafeMemory.readInteger()); 438 | } 439 | } 440 | 441 | static class IntegerVolatileDeserializer implements Deserializer { 442 | @Override 443 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 444 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readInteger()); 445 | } 446 | } 447 | 448 | static class LongWrapperSerializer implements Serializer { 449 | @Override 450 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 451 | unsafeMemory.writeLongWrapper((Long) unsafe.getObject(object, offset)); 452 | } 453 | } 454 | 455 | static class LongWrapperVolatileSerializer implements Serializer { 456 | @Override 457 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 458 | unsafeMemory.writeLongWrapper((Long) unsafe.getObjectVolatile(object, offset)); 459 | } 460 | } 461 | 462 | static class LongWrapperDeserializer implements Deserializer { 463 | @Override 464 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 465 | unsafe.putObject(object, offset, unsafeMemory.readLongWrapper()); 466 | } 467 | } 468 | 469 | static class LongWrapperVolatileDeserializer implements Deserializer { 470 | @Override 471 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 472 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readLongWrapper()); 473 | } 474 | } 475 | 476 | static class DoubleWrapperSerializer implements Serializer { 477 | @Override 478 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 479 | unsafeMemory.writeDoubleWrapper((Double) unsafe.getObject(object, offset)); 480 | } 481 | } 482 | 483 | static class DoubleWrapperVolatileSerializer implements Serializer { 484 | @Override 485 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 486 | unsafeMemory.writeDoubleWrapper((Double) unsafe.getObjectVolatile(object, offset)); 487 | } 488 | } 489 | 490 | static class DoubleWrapperDeserializer implements Deserializer { 491 | @Override 492 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 493 | unsafe.putObject(object, offset, unsafeMemory.readDoubleWrapper()); 494 | } 495 | } 496 | 497 | static class DoubleWrapperVolatileDeserializer implements Deserializer { 498 | @Override 499 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 500 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readDoubleWrapper()); 501 | } 502 | } 503 | 504 | static class ShortWrapperSerializer implements Serializer { 505 | @Override 506 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 507 | unsafeMemory.writeShortWrapper((Short) unsafe.getObject(object, offset)); 508 | } 509 | } 510 | 511 | static class ShortWrapperVolatileSerializer implements Serializer { 512 | @Override 513 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 514 | unsafeMemory.writeShortWrapper((Short) unsafe.getObjectVolatile(object, offset)); 515 | } 516 | } 517 | 518 | static class ShortWrapperDeserializer implements Deserializer { 519 | @Override 520 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 521 | unsafe.putObject(object, offset, unsafeMemory.readShortWrapper()); 522 | } 523 | } 524 | 525 | static class ShortWrapperVolatileDeserializer implements Deserializer { 526 | @Override 527 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 528 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readShortWrapper()); 529 | } 530 | } 531 | 532 | static class FloatWrapperSerializer implements Serializer { 533 | @Override 534 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 535 | unsafeMemory.writeFloatWrapper((Float) unsafe.getObject(object, offset)); 536 | } 537 | } 538 | 539 | static class FloatWrapperVolatileSerializer implements Serializer { 540 | @Override 541 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 542 | unsafeMemory.writeFloatWrapper((Float) unsafe.getObjectVolatile(object, offset)); 543 | } 544 | } 545 | 546 | static class FloatWrapperDeserializer implements Deserializer { 547 | @Override 548 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 549 | unsafe.putObject(object, offset, unsafeMemory.readFloatWrapper()); 550 | } 551 | } 552 | 553 | static class FloatWrapperVolatileDeserializer implements Deserializer { 554 | @Override 555 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 556 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readFloatWrapper()); 557 | } 558 | } 559 | 560 | static class CharacterSerializer implements Serializer { 561 | @Override 562 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 563 | unsafeMemory.writeCharacter((Character) unsafe.getObject(object, offset)); 564 | } 565 | } 566 | 567 | static class CharacterVolatileSerializer implements Serializer { 568 | @Override 569 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 570 | unsafeMemory.writeCharacter((Character) unsafe.getObjectVolatile(object, offset)); 571 | } 572 | } 573 | 574 | static class CharacterDeserializer implements Deserializer { 575 | @Override 576 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 577 | unsafe.putObject(object, offset, unsafeMemory.readCharacter()); 578 | } 579 | } 580 | 581 | static class CharacterVolatileDeserializer implements Deserializer { 582 | @Override 583 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 584 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readCharacter()); 585 | } 586 | } 587 | 588 | static class ByteWrapperSerializer implements Serializer { 589 | @Override 590 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 591 | unsafeMemory.writeByteWrapper((Byte) unsafe.getObject(object, offset)); 592 | } 593 | } 594 | 595 | static class ByteWrapperVolatileSerializer implements Serializer { 596 | @Override 597 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 598 | unsafeMemory.writeByteWrapper((Byte) unsafe.getObjectVolatile(object, offset)); 599 | } 600 | } 601 | 602 | static class ByteWrapperDeserializer implements Deserializer { 603 | @Override 604 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 605 | unsafe.putObject(object, offset, unsafeMemory.readByteWrapper()); 606 | } 607 | } 608 | 609 | static class ByteWrapperVolatileDeserializer implements Deserializer { 610 | @Override 611 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 612 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readByteWrapper()); 613 | } 614 | } 615 | 616 | static class BooleanWrapperSerializer implements Serializer { 617 | @Override 618 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 619 | unsafeMemory.writeBooleanWrapper((Boolean) unsafe.getObject(object, offset)); 620 | } 621 | } 622 | 623 | static class BooleanWrapperVolatileSerializer implements Serializer { 624 | @Override 625 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 626 | unsafeMemory.writeBooleanWrapper((Boolean) unsafe.getObjectVolatile(object, offset)); 627 | } 628 | } 629 | 630 | static class BooleanWrapperDeserializer implements Deserializer { 631 | @Override 632 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 633 | unsafe.putObject(object, offset, unsafeMemory.readBooleanWrapper()); 634 | } 635 | } 636 | 637 | static class BooleanWrapperVolatileDeserializer implements Deserializer { 638 | @Override 639 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 640 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readBooleanWrapper()); 641 | } 642 | } 643 | 644 | static class CharArraySerializer implements Serializer { 645 | @Override 646 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 647 | unsafeMemory.writeCharArray((char[]) unsafe.getObject(object, offset)); 648 | } 649 | } 650 | 651 | static class CharArrayVolatileSerializer implements Serializer { 652 | @Override 653 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 654 | unsafeMemory.writeCharArray((char[]) unsafe.getObjectVolatile(object, offset)); 655 | } 656 | } 657 | 658 | static class CharArrayDeserializer implements Deserializer { 659 | @Override 660 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 661 | unsafe.putObject(object, offset, unsafeMemory.readCharArray()); 662 | } 663 | } 664 | 665 | static class CharArrayVolatileDeserializer implements Deserializer { 666 | @Override 667 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 668 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readCharArray()); 669 | } 670 | } 671 | 672 | static class IntArraySerializer implements Serializer { 673 | @Override 674 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 675 | unsafeMemory.writeIntArray((int[]) unsafe.getObject(object, offset)); 676 | } 677 | } 678 | 679 | static class Int2DArraySerializer implements Serializer { 680 | @Override 681 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 682 | int[][] ints = (int[][]) unsafe.getObject(object, offset); 683 | if (!writeNullableObject(unsafeMemory, ints)) { 684 | unsafeMemory.writeInt(ints.length); 685 | for (int[] anInt : ints) { 686 | unsafeMemory.writeIntArray(anInt); 687 | } 688 | } 689 | } 690 | } 691 | 692 | static class Int2DArrayVolatileSerializer implements Serializer { 693 | @Override 694 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 695 | int[][] ints = (int[][]) unsafe.getObjectVolatile(object, offset); 696 | if (!writeNullableObject(unsafeMemory, ints)) { 697 | unsafeMemory.writeInt(ints.length); 698 | for (int[] anInt : ints) { 699 | unsafeMemory.writeIntArray(anInt); 700 | } 701 | } 702 | } 703 | } 704 | 705 | static class Long2DArraySerializer implements Serializer { 706 | @Override 707 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 708 | long[][] longs = (long[][]) unsafe.getObject(object, offset); 709 | if (!writeNullableObject(unsafeMemory, longs)) { 710 | unsafeMemory.writeInt(longs.length); 711 | for (long[] aLong : longs) { 712 | unsafeMemory.writeLongArray(aLong); 713 | } 714 | } 715 | } 716 | } 717 | 718 | static class Long2DArrayVolatileSerializer implements Serializer { 719 | @Override 720 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 721 | long[][] longs = (long[][]) unsafe.getObjectVolatile(object, offset); 722 | if (!writeNullableObject(unsafeMemory, longs)) { 723 | unsafeMemory.writeInt(longs.length); 724 | for (long[] aLong : longs) { 725 | unsafeMemory.writeLongArray(aLong); 726 | } 727 | } 728 | } 729 | } 730 | 731 | static class Double2DArraySerializer implements Serializer { 732 | @Override 733 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 734 | double[][] doubles = (double[][]) unsafe.getObject(object, offset); 735 | if (!writeNullableObject(unsafeMemory, doubles)) { 736 | unsafeMemory.writeInt(doubles.length); 737 | for (double[] aDouble : doubles) { 738 | unsafeMemory.writeDoubleArray(aDouble); 739 | } 740 | } 741 | } 742 | } 743 | 744 | static class Double2DArrayVolatileSerializer implements Serializer { 745 | @Override 746 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 747 | double[][] doubles = (double[][]) unsafe.getObjectVolatile(object, offset); 748 | if (!writeNullableObject(unsafeMemory, doubles)) { 749 | unsafeMemory.writeInt(doubles.length); 750 | for (double[] aDouble : doubles) { 751 | unsafeMemory.writeDoubleArray(aDouble); 752 | } 753 | } 754 | } 755 | } 756 | 757 | static class Float2DArraySerializer implements Serializer { 758 | @Override 759 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 760 | float[][] floats = (float[][]) unsafe.getObject(object, offset); 761 | if (!writeNullableObject(unsafeMemory, floats)) { 762 | unsafeMemory.writeInt(floats.length); 763 | for (float[] aFloat : floats) { 764 | unsafeMemory.writeFloatArray(aFloat); 765 | } 766 | } 767 | } 768 | } 769 | 770 | static class Float2DArrayVolatileSerializer implements Serializer { 771 | @Override 772 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 773 | float[][] floats = (float[][]) unsafe.getObjectVolatile(object, offset); 774 | if (!writeNullableObject(unsafeMemory, floats)) { 775 | unsafeMemory.writeInt(floats.length); 776 | for (float[] aFloat : floats) { 777 | unsafeMemory.writeFloatArray(aFloat); 778 | } 779 | } 780 | } 781 | } 782 | 783 | static class Short2DArraySerializer implements Serializer { 784 | @Override 785 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 786 | short[][] shorts = (short[][]) unsafe.getObject(object, offset); 787 | if (!writeNullableObject(unsafeMemory, shorts)) { 788 | unsafeMemory.writeInt(shorts.length); 789 | for (short[] aShort : shorts) { 790 | unsafeMemory.writeShortArray(aShort); 791 | } 792 | } 793 | } 794 | } 795 | 796 | static class Short2DArrayVolatileSerializer implements Serializer { 797 | @Override 798 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 799 | short[][] shorts = (short[][]) unsafe.getObjectVolatile(object, offset); 800 | if (!writeNullableObject(unsafeMemory, shorts)) { 801 | unsafeMemory.writeInt(shorts.length); 802 | for (short[] aShort : shorts) { 803 | unsafeMemory.writeShortArray(aShort); 804 | } 805 | } 806 | } 807 | } 808 | 809 | static class Char2DArraySerializer implements Serializer { 810 | @Override 811 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 812 | char[][] chars = (char[][]) unsafe.getObject(object, offset); 813 | if (!writeNullableObject(unsafeMemory, chars)) { 814 | unsafeMemory.writeInt(chars.length); 815 | for (char[] aChar : chars) { 816 | unsafeMemory.writeCharArray(aChar); 817 | } 818 | } 819 | } 820 | } 821 | 822 | static class Char2DArrayVolatileSerializer implements Serializer { 823 | @Override 824 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 825 | char[][] chars = (char[][]) unsafe.getObjectVolatile(object, offset); 826 | if (!writeNullableObject(unsafeMemory, chars)) { 827 | unsafeMemory.writeInt(chars.length); 828 | for (char[] aChar : chars) { 829 | unsafeMemory.writeCharArray(aChar); 830 | } 831 | } 832 | } 833 | } 834 | 835 | static class String2DArraySerializer implements Serializer { 836 | @Override 837 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 838 | String[][] strings_2d = (String[][]) unsafe.getObject(object, offset); 839 | if (writeNullableObject(unsafeMemory, strings_2d)) { 840 | return; 841 | } 842 | unsafeMemory.writeInt(strings_2d.length); 843 | for (String[] stringArray : strings_2d) { 844 | if (writeNullableObject(unsafeMemory, stringArray)) { 845 | continue; 846 | } 847 | unsafeMemory.writeInt(stringArray.length); 848 | for (String value : stringArray) { 849 | if (!writeNullableObject(unsafeMemory, value)) { 850 | unsafeMemory.writeString(value); 851 | } 852 | } 853 | 854 | } 855 | 856 | } 857 | } 858 | 859 | static class String2DArrayVolatileSerializer implements Serializer { 860 | @Override 861 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 862 | String[][] strings_2d = (String[][]) unsafe.getObjectVolatile(object, offset); 863 | if (writeNullableObject(unsafeMemory, strings_2d)) { 864 | return; 865 | } 866 | unsafeMemory.writeInt(strings_2d.length); 867 | for (String[] stringArray : strings_2d) { 868 | if (writeNullableObject(unsafeMemory, stringArray)) { 869 | continue; 870 | } 871 | unsafeMemory.writeInt(stringArray.length); 872 | for (String value : stringArray) { 873 | if (!writeNullableObject(unsafeMemory, value)) { 874 | unsafeMemory.writeString(value); 875 | } 876 | } 877 | 878 | } 879 | 880 | } 881 | } 882 | 883 | static class String2DArrayDeserializer implements Deserializer { 884 | @Override 885 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 886 | if (readNullableObject(unsafeMemory)) { 887 | return; 888 | } 889 | String[][] strings_2d = new String[unsafeMemory.readInt()][]; 890 | for (int i = 0; i < strings_2d.length; i++) { 891 | if (readNullableObject(unsafeMemory)) { 892 | continue; 893 | } 894 | strings_2d[i] = new String[unsafeMemory.readInt()]; 895 | for (int j = 0; j < strings_2d[i].length; j++) { 896 | if (!readNullableObject(unsafeMemory)) { 897 | strings_2d[i][j] = unsafeMemory.readString(); 898 | } 899 | } 900 | 901 | } 902 | unsafe.putObject(object, offset, strings_2d); 903 | 904 | } 905 | } 906 | 907 | static class String2DArrayVolatileDeserializer implements Deserializer { 908 | @Override 909 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 910 | if (readNullableObject(unsafeMemory)) { 911 | return; 912 | } 913 | String[][] strings_2d = new String[unsafeMemory.readInt()][]; 914 | for (int i = 0; i < strings_2d.length; i++) { 915 | if (readNullableObject(unsafeMemory)) { 916 | continue; 917 | } 918 | strings_2d[i] = new String[unsafeMemory.readInt()]; 919 | for (int j = 0; j < strings_2d[i].length; j++) { 920 | if (!readNullableObject(unsafeMemory)) { 921 | strings_2d[i][j] = unsafeMemory.readString(); 922 | } 923 | } 924 | 925 | } 926 | unsafe.putObjectVolatile(object, offset, strings_2d); 927 | 928 | } 929 | } 930 | 931 | static class Byte2DArraySerializer implements Serializer { 932 | @Override 933 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 934 | byte[][] bytes = (byte[][]) unsafe.getObject(object, offset); 935 | if (!writeNullableObject(unsafeMemory, bytes)) { 936 | unsafeMemory.writeInt(bytes.length); 937 | for (byte[] aByte : bytes) { 938 | unsafeMemory.writeByteArray(aByte); 939 | } 940 | } 941 | } 942 | } 943 | 944 | static class Byte2DArrayVolatileSerializer implements Serializer { 945 | @Override 946 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 947 | byte[][] bytes = (byte[][]) unsafe.getObjectVolatile(object, offset); 948 | if (!writeNullableObject(unsafeMemory, bytes)) { 949 | unsafeMemory.writeInt(bytes.length); 950 | for (byte[] aByte : bytes) { 951 | unsafeMemory.writeByteArray(aByte); 952 | } 953 | } 954 | } 955 | } 956 | 957 | static class Boolean2DArraySerializer implements Serializer { 958 | @Override 959 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 960 | boolean[][] booleans = (boolean[][]) unsafe.getObject(object, offset); 961 | if (!writeNullableObject(unsafeMemory, booleans)) { 962 | unsafeMemory.writeInt(booleans.length); 963 | for (boolean[] aBoolean : booleans) { 964 | unsafeMemory.writeBooleanArray(aBoolean); 965 | } 966 | } 967 | } 968 | } 969 | 970 | static class Boolean2DArrayVolatileSerializer implements Serializer { 971 | @Override 972 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 973 | boolean[][] booleans = (boolean[][]) unsafe.getObjectVolatile(object, offset); 974 | if (!writeNullableObject(unsafeMemory, booleans)) { 975 | unsafeMemory.writeInt(booleans.length); 976 | for (boolean[] aBoolean : booleans) { 977 | unsafeMemory.writeBooleanArray(aBoolean); 978 | } 979 | } 980 | } 981 | } 982 | 983 | static class IntArrayVolatileSerializer implements Serializer { 984 | @Override 985 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 986 | unsafeMemory.writeIntArray((int[]) unsafe.getObjectVolatile(object, offset)); 987 | } 988 | } 989 | 990 | static class IntArrayDeserializer implements Deserializer { 991 | @Override 992 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 993 | unsafe.putObject(object, offset, unsafeMemory.readIntArray()); 994 | } 995 | } 996 | 997 | static class Int2DArrayDeserializer implements Deserializer { 998 | @Override 999 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1000 | if (!readNullableObject(unsafeMemory)) { 1001 | int[][] ints_2d = new int[unsafeMemory.readInt()][]; 1002 | for (int i = 0; i < ints_2d.length; i++) { 1003 | ints_2d[i] = unsafeMemory.readIntArray(); 1004 | } 1005 | unsafe.putObject(object, offset, ints_2d); 1006 | } 1007 | } 1008 | } 1009 | 1010 | static class Int2DArrayVolatileDeserializer implements Deserializer { 1011 | @Override 1012 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1013 | if (!readNullableObject(unsafeMemory)) { 1014 | int[][] ints_2d = new int[unsafeMemory.readInt()][]; 1015 | for (int i = 0; i < ints_2d.length; i++) { 1016 | ints_2d[i] = unsafeMemory.readIntArray(); 1017 | } 1018 | unsafe.putObjectVolatile(object, offset, ints_2d); 1019 | } 1020 | } 1021 | } 1022 | 1023 | static class Long2DArrayDeserializer implements Deserializer { 1024 | @Override 1025 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1026 | if (!readNullableObject(unsafeMemory)) { 1027 | long[][] longs_2d = new long[unsafeMemory.readInt()][]; 1028 | for (int i = 0; i < longs_2d.length; i++) { 1029 | longs_2d[i] = unsafeMemory.readLongArray(); 1030 | } 1031 | unsafe.putObject(object, offset, longs_2d); 1032 | } 1033 | } 1034 | } 1035 | 1036 | static class Long2DArrayVolatileDeserializer implements Deserializer { 1037 | @Override 1038 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1039 | if (!readNullableObject(unsafeMemory)) { 1040 | long[][] longs_2d = new long[unsafeMemory.readInt()][]; 1041 | for (int i = 0; i < longs_2d.length; i++) { 1042 | longs_2d[i] = unsafeMemory.readLongArray(); 1043 | } 1044 | unsafe.putObjectVolatile(object, offset, longs_2d); 1045 | } 1046 | } 1047 | } 1048 | 1049 | static class Double2DArrayDeserializer implements Deserializer { 1050 | @Override 1051 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1052 | if (!readNullableObject(unsafeMemory)) { 1053 | double[][] doubles_2d = new double[unsafeMemory.readInt()][]; 1054 | for (int i = 0; i < doubles_2d.length; i++) { 1055 | doubles_2d[i] = unsafeMemory.readDoubleArray(); 1056 | } 1057 | unsafe.putObject(object, offset, doubles_2d); 1058 | } 1059 | } 1060 | } 1061 | 1062 | static class Double2DArrayVolatileDeserializer implements Deserializer { 1063 | @Override 1064 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1065 | if (!readNullableObject(unsafeMemory)) { 1066 | double[][] doubles_2d = new double[unsafeMemory.readInt()][]; 1067 | for (int i = 0; i < doubles_2d.length; i++) { 1068 | doubles_2d[i] = unsafeMemory.readDoubleArray(); 1069 | } 1070 | unsafe.putObjectVolatile(object, offset, doubles_2d); 1071 | } 1072 | } 1073 | } 1074 | 1075 | static class Float2DArrayDeserializer implements Deserializer { 1076 | @Override 1077 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1078 | if (!readNullableObject(unsafeMemory)) { 1079 | float[][] floats_2d = new float[unsafeMemory.readInt()][]; 1080 | for (int i = 0; i < floats_2d.length; i++) { 1081 | floats_2d[i] = unsafeMemory.readFloatArray(); 1082 | } 1083 | unsafe.putObject(object, offset, floats_2d); 1084 | } 1085 | } 1086 | } 1087 | 1088 | static class Float2DArrayVolatileDeserializer implements Deserializer { 1089 | @Override 1090 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1091 | if (!readNullableObject(unsafeMemory)) { 1092 | float[][] floats_2d = new float[unsafeMemory.readInt()][]; 1093 | for (int i = 0; i < floats_2d.length; i++) { 1094 | floats_2d[i] = unsafeMemory.readFloatArray(); 1095 | } 1096 | unsafe.putObjectVolatile(object, offset, floats_2d); 1097 | } 1098 | } 1099 | } 1100 | 1101 | static class Short2DArrayDeserializer implements Deserializer { 1102 | @Override 1103 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1104 | if (!readNullableObject(unsafeMemory)) { 1105 | short[][] shorts_2d = new short[unsafeMemory.readInt()][]; 1106 | for (int i = 0; i < shorts_2d.length; i++) { 1107 | shorts_2d[i] = unsafeMemory.readShortArray(); 1108 | } 1109 | unsafe.putObject(object, offset, shorts_2d); 1110 | } 1111 | } 1112 | } 1113 | 1114 | static class Short2DArrayVolatileDeserializer implements Deserializer { 1115 | @Override 1116 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1117 | if (!readNullableObject(unsafeMemory)) { 1118 | short[][] shorts_2d = new short[unsafeMemory.readInt()][]; 1119 | for (int i = 0; i < shorts_2d.length; i++) { 1120 | shorts_2d[i] = unsafeMemory.readShortArray(); 1121 | } 1122 | unsafe.putObjectVolatile(object, offset, shorts_2d); 1123 | } 1124 | } 1125 | } 1126 | 1127 | static class Char2DArrayDeserializer implements Deserializer { 1128 | @Override 1129 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1130 | if (!readNullableObject(unsafeMemory)) { 1131 | char[][] chars_2d = new char[unsafeMemory.readInt()][]; 1132 | for (int i = 0; i < chars_2d.length; i++) { 1133 | chars_2d[i] = unsafeMemory.readCharArray(); 1134 | } 1135 | unsafe.putObject(object, offset, chars_2d); 1136 | } 1137 | } 1138 | } 1139 | 1140 | static class Char2DArrayVolatileDeserializer implements Deserializer { 1141 | @Override 1142 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1143 | if (!readNullableObject(unsafeMemory)) { 1144 | char[][] chars_2d = new char[unsafeMemory.readInt()][]; 1145 | for (int i = 0; i < chars_2d.length; i++) { 1146 | chars_2d[i] = unsafeMemory.readCharArray(); 1147 | } 1148 | unsafe.putObjectVolatile(object, offset, chars_2d); 1149 | } 1150 | } 1151 | } 1152 | 1153 | 1154 | static class Byte2DArrayDeserializer implements Deserializer { 1155 | @Override 1156 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1157 | if (!readNullableObject(unsafeMemory)) { 1158 | byte[][] bytes_2d = new byte[unsafeMemory.readInt()][]; 1159 | for (int i = 0; i < bytes_2d.length; i++) { 1160 | bytes_2d[i] = unsafeMemory.readByteArray(); 1161 | } 1162 | unsafe.putObject(object, offset, bytes_2d); 1163 | } 1164 | } 1165 | } 1166 | 1167 | static class Byte2DArrayVolatileDeserializer implements Deserializer { 1168 | @Override 1169 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1170 | if (!readNullableObject(unsafeMemory)) { 1171 | byte[][] bytes_2d = new byte[unsafeMemory.readInt()][]; 1172 | for (int i = 0; i < bytes_2d.length; i++) { 1173 | bytes_2d[i] = unsafeMemory.readByteArray(); 1174 | } 1175 | unsafe.putObjectVolatile(object, offset, bytes_2d); 1176 | } 1177 | } 1178 | } 1179 | 1180 | static class Boolean2DArrayDeserializer implements Deserializer { 1181 | @Override 1182 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1183 | if (!readNullableObject(unsafeMemory)) { 1184 | boolean[][] booleans_2d = new boolean[unsafeMemory.readInt()][]; 1185 | for (int i = 0; i < booleans_2d.length; i++) { 1186 | booleans_2d[i] = unsafeMemory.readBooleanArray(); 1187 | } 1188 | unsafe.putObject(object, offset, booleans_2d); 1189 | } 1190 | } 1191 | } 1192 | 1193 | static class Boolean2DArrayVolatileDeserializer implements Deserializer { 1194 | @Override 1195 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1196 | if (!readNullableObject(unsafeMemory)) { 1197 | boolean[][] booleans_2d = new boolean[unsafeMemory.readInt()][]; 1198 | for (int i = 0; i < booleans_2d.length; i++) { 1199 | booleans_2d[i] = unsafeMemory.readBooleanArray(); 1200 | } 1201 | unsafe.putObjectVolatile(object, offset, booleans_2d); 1202 | } 1203 | } 1204 | } 1205 | 1206 | static class IntArrayVolatileDeserializer implements Deserializer { 1207 | @Override 1208 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1209 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readIntArray()); 1210 | } 1211 | } 1212 | 1213 | static class ShortArraySerializer implements Serializer { 1214 | @Override 1215 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1216 | unsafeMemory.writeShortArray((short[]) unsafe.getObject(object, offset)); 1217 | } 1218 | } 1219 | 1220 | static class ShortArrayVolatileSerializer implements Serializer { 1221 | @Override 1222 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1223 | unsafeMemory.writeShortArray((short[]) unsafe.getObjectVolatile(object, offset)); 1224 | } 1225 | } 1226 | 1227 | static class ShortArrayDeserializer implements Deserializer { 1228 | @Override 1229 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1230 | unsafe.putObject(object, offset, unsafeMemory.readShortArray()); 1231 | } 1232 | } 1233 | 1234 | static class ShortArrayVolatileDeserializer implements Deserializer { 1235 | @Override 1236 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1237 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readShortArray()); 1238 | } 1239 | } 1240 | 1241 | static class LongArraySerializer implements Serializer { 1242 | @Override 1243 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1244 | unsafeMemory.writeLongArray((long[]) unsafe.getObject(object, offset)); 1245 | } 1246 | } 1247 | 1248 | static class LongArrayVolatileSerializer implements Serializer { 1249 | @Override 1250 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1251 | unsafeMemory.writeLongArray((long[]) unsafe.getObjectVolatile(object, offset)); 1252 | } 1253 | } 1254 | 1255 | static class LongArrayDeserializer implements Deserializer { 1256 | @Override 1257 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1258 | unsafe.putObject(object, offset, unsafeMemory.readLongArray()); 1259 | } 1260 | } 1261 | 1262 | static class LongArrayVolatileDeserializer implements Deserializer { 1263 | @Override 1264 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1265 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readLongArray()); 1266 | } 1267 | } 1268 | 1269 | static class DoubleArraySerializer implements Serializer { 1270 | @Override 1271 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1272 | unsafeMemory.writeDoubleArray((double[]) unsafe.getObject(object, offset)); 1273 | } 1274 | } 1275 | 1276 | static class DoubleArrayVolatileSerializer implements Serializer { 1277 | @Override 1278 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1279 | unsafeMemory.writeDoubleArray((double[]) unsafe.getObjectVolatile(object, offset)); 1280 | } 1281 | } 1282 | 1283 | static class DoubleArrayDeserializer implements Deserializer { 1284 | @Override 1285 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1286 | unsafe.putObject(object, offset, unsafeMemory.readDoubleArray()); 1287 | } 1288 | } 1289 | 1290 | static class DoubleArrayVolatileDeserializer implements Deserializer { 1291 | @Override 1292 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1293 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readDoubleArray()); 1294 | } 1295 | } 1296 | 1297 | static class FloatArraySerializer implements Serializer { 1298 | @Override 1299 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1300 | unsafeMemory.writeFloatArray((float[]) unsafe.getObject(object, offset)); 1301 | } 1302 | } 1303 | 1304 | static class FloatArrayVolatileSerializer implements Serializer { 1305 | @Override 1306 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1307 | unsafeMemory.writeFloatArray((float[]) unsafe.getObjectVolatile(object, offset)); 1308 | } 1309 | } 1310 | 1311 | static class FloatArrayDeserializer implements Deserializer { 1312 | @Override 1313 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1314 | unsafe.putObject(object, offset, unsafeMemory.readFloatArray()); 1315 | } 1316 | } 1317 | 1318 | static class FloatArrayVolatileDeserializer implements Deserializer { 1319 | @Override 1320 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1321 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readFloatArray()); 1322 | } 1323 | } 1324 | 1325 | static class BooleanArraySerializer implements Serializer { 1326 | @Override 1327 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1328 | unsafeMemory.writeBooleanArray((boolean[]) unsafe.getObject(object, offset)); 1329 | } 1330 | } 1331 | 1332 | static class BooleanArrayVolatileSerializer implements Serializer { 1333 | @Override 1334 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1335 | unsafeMemory.writeBooleanArray((boolean[]) unsafe.getObjectVolatile(object, offset)); 1336 | } 1337 | } 1338 | 1339 | static class BooleanArrayDeserializer implements Deserializer { 1340 | @Override 1341 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1342 | unsafe.putObject(object, offset, unsafeMemory.readBooleanArray()); 1343 | } 1344 | } 1345 | 1346 | static class BooleanArrayVolatileDeserializer implements Deserializer { 1347 | @Override 1348 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1349 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readBooleanArray()); 1350 | } 1351 | } 1352 | 1353 | static class ByteArraySerializer implements Serializer { 1354 | @Override 1355 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1356 | unsafeMemory.writeByteArray((byte[]) unsafe.getObject(object, offset)); 1357 | } 1358 | } 1359 | 1360 | static class ByteArrayVolatileSerializer implements Serializer { 1361 | @Override 1362 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1363 | unsafeMemory.writeByteArray((byte[]) unsafe.getObjectVolatile(object, offset)); 1364 | } 1365 | } 1366 | 1367 | static class ByteArrayDeserializer implements Deserializer { 1368 | @Override 1369 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1370 | unsafe.putObject(object, offset, unsafeMemory.readByteArray()); 1371 | } 1372 | } 1373 | 1374 | static class ByteArrayVolatileDeserializer implements Deserializer { 1375 | @Override 1376 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1377 | unsafe.putObjectVolatile(object, offset, unsafeMemory.readByteArray()); 1378 | } 1379 | } 1380 | 1381 | static class StringArraySerializer implements Serializer { 1382 | @Override 1383 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1384 | String[] stringArray = (String[]) unsafe.getObject(object, offset); 1385 | if (!writeNullableObject(unsafeMemory, stringArray)) { 1386 | unsafeMemory.writeInt(stringArray.length); 1387 | for (String value : stringArray) { 1388 | if (!writeNullableObject(unsafeMemory, value)) { 1389 | unsafeMemory.writeString(value); 1390 | } 1391 | } 1392 | } 1393 | } 1394 | } 1395 | 1396 | static class StringArrayVolatileSerializer implements Serializer { 1397 | @Override 1398 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1399 | String[] stringArray = (String[]) unsafe.getObjectVolatile(object, offset); 1400 | if (!writeNullableObject(unsafeMemory, stringArray)) { 1401 | unsafeMemory.writeInt(stringArray.length); 1402 | for (String value : stringArray) { 1403 | if (!writeNullableObject(unsafeMemory, value)) { 1404 | unsafeMemory.writeString(value); 1405 | } 1406 | } 1407 | } 1408 | } 1409 | } 1410 | 1411 | static class StringArrayDeserializer implements Deserializer { 1412 | @Override 1413 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1414 | String[] values = null; 1415 | if (!readNullableObject(unsafeMemory)) { 1416 | values = new String[unsafeMemory.readInt()]; 1417 | for (int i = 0; i < values.length; i++) { 1418 | if (!readNullableObject(unsafeMemory)) { 1419 | values[i] = unsafeMemory.readString(); 1420 | } 1421 | } 1422 | } 1423 | unsafe.putObject(object, offset, values); 1424 | } 1425 | } 1426 | 1427 | static class StringArrayVolatileDeserializer implements Deserializer { 1428 | @Override 1429 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1430 | String[] values = null; 1431 | if (!readNullableObject(unsafeMemory)) { 1432 | values = new String[unsafeMemory.readInt()]; 1433 | for (int i = 0; i < values.length; i++) { 1434 | if (!readNullableObject(unsafeMemory)) { 1435 | values[i] = unsafeMemory.readString(); 1436 | } 1437 | } 1438 | } 1439 | unsafe.putObjectVolatile(object, offset, values); 1440 | } 1441 | } 1442 | 1443 | static class EnumSerializer implements Serializer { 1444 | @Override 1445 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1446 | Object ordinal = unsafe.getInt(object, offset); 1447 | unsafeMemory.writeInt((int) ordinal); 1448 | } 1449 | } 1450 | 1451 | static class EnumVolatileSerializer extends EnumSerializer { 1452 | } 1453 | 1454 | static class BigIntegerSerializer implements Serializer { 1455 | @Override 1456 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1457 | serializeObject(bigIntegerClassInfo, unsafeMemory, object, offset); 1458 | } 1459 | } 1460 | 1461 | static class BigIntegerVolatileSerializer implements Serializer { 1462 | @Override 1463 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1464 | serializeVolatileObject(bigIntegerClassInfo, unsafeMemory, object, offset); 1465 | } 1466 | } 1467 | 1468 | static class BigIntegerDeserializer implements Deserializer { 1469 | @Override 1470 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1471 | deserializeObject(bigIntegerClassInfo, unsafeMemory, object, offset); 1472 | } 1473 | } 1474 | 1475 | static class BigIntegerVolatileDeserializer implements Deserializer { 1476 | @Override 1477 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1478 | deserializeVolatileObject(bigIntegerClassInfo, unsafeMemory, object, offset); 1479 | } 1480 | } 1481 | 1482 | static class BatchSerializer implements Serializer { 1483 | private final int size; 1484 | 1485 | BatchSerializer(int size) { 1486 | this.size = size; 1487 | } 1488 | 1489 | @Override 1490 | public void serialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1491 | unsafeMemory.writeBatch(object, offset, size); 1492 | } 1493 | } 1494 | 1495 | static class BatchDeserializer implements Deserializer { 1496 | private final int size; 1497 | 1498 | BatchDeserializer(int size) { 1499 | this.size = size; 1500 | } 1501 | 1502 | @Override 1503 | public void deserialize(UnsafeMemory unsafeMemory, Object object, long offset) { 1504 | unsafeMemory.readBatch(object, offset, size); 1505 | } 1506 | } 1507 | 1508 | 1509 | } 1510 | -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/TypeRepository.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import java.math.BigInteger; 4 | import java.util.Date; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import static com.mojang.blixtser.core.SerializationUtils.*; 9 | 10 | public abstract class TypeRepository { 11 | 12 | static final TypeRepository volatileTypeRepository = new VolatileTypeRepository(); 13 | static final TypeRepository nonVolatileTypeRepository = new NonVolatileTypeRepository(); 14 | 15 | private static final Map typeSizes = new HashMap<>(8); 16 | 17 | static { 18 | typeSizes.put(long.class, 8); 19 | typeSizes.put(double.class, 8); 20 | typeSizes.put(int.class, 4); 21 | typeSizes.put(float.class, 4); 22 | typeSizes.put(char.class, 2); 23 | typeSizes.put(short.class, 2); 24 | typeSizes.put(boolean.class, 1); 25 | typeSizes.put(byte.class, 1); 26 | } 27 | 28 | static long sizeOf(Class type) { 29 | return typeSizes.get(type); 30 | } 31 | 32 | public abstract Serializer getSerializer(Class type); 33 | 34 | public abstract Deserializer getDeserializer(Class type); 35 | 36 | public abstract boolean serializerDeserializerExistsFor(Class type); 37 | 38 | 39 | /** 40 | * 41 | */ 42 | static class NonVolatileTypeRepository extends TypeRepository { 43 | 44 | private final Map serializers = new HashMap<>(64); 45 | private final Map deserializers = new HashMap<>(64); 46 | 47 | NonVolatileTypeRepository() { 48 | buildSerializers(); 49 | buildDeserializers(); 50 | } 51 | 52 | public Serializer getSerializer(Class type) { 53 | return serializers.get(type); 54 | } 55 | 56 | public Deserializer getDeserializer(Class type) { 57 | return deserializers.get(type); 58 | } 59 | 60 | public boolean serializerDeserializerExistsFor(Class type) { 61 | return serializers.containsKey(type) && deserializers.containsKey(type); 62 | } 63 | 64 | private void buildSerializers() { 65 | serializers.put(int.class, new IntSerializer()); 66 | serializers.put(int[].class, new IntArraySerializer()); 67 | serializers.put(int[][].class, new Int2DArraySerializer()); 68 | serializers.put(Integer.class, new IntegerSerializer()); 69 | serializers.put(BigInteger.class, new BigIntegerSerializer()); 70 | 71 | serializers.put(long.class, new LongSerializer()); 72 | serializers.put(long[].class, new LongArraySerializer()); 73 | serializers.put(long[][].class, new Long2DArraySerializer()); 74 | serializers.put(Long.class, new LongWrapperSerializer()); 75 | 76 | serializers.put(short.class, new ShortSerializer()); 77 | serializers.put(short[].class, new ShortArraySerializer()); 78 | serializers.put(short[][].class, new Short2DArraySerializer()); 79 | serializers.put(Short.class, new ShortWrapperSerializer()); 80 | 81 | serializers.put(byte.class, new ByteSerializer()); 82 | serializers.put(byte[].class, new ByteArraySerializer()); 83 | serializers.put(byte[][].class, new Byte2DArraySerializer()); 84 | serializers.put(Byte.class, new ByteWrapperSerializer()); 85 | 86 | serializers.put(char.class, new CharSerializer()); 87 | serializers.put(char[].class, new CharArraySerializer()); 88 | serializers.put(char[][].class, new Char2DArraySerializer()); 89 | serializers.put(Character.class, new CharacterSerializer()); 90 | 91 | serializers.put(boolean.class, new BooleanSerializer()); 92 | serializers.put(boolean[].class, new BooleanArraySerializer()); 93 | serializers.put(boolean[][].class, new Boolean2DArraySerializer()); 94 | serializers.put(Boolean.class, new BooleanWrapperSerializer()); 95 | 96 | serializers.put(float.class, new FloatSerializer()); 97 | serializers.put(float[].class, new FloatArraySerializer()); 98 | serializers.put(float[][].class, new Float2DArraySerializer()); 99 | serializers.put(Float.class, new FloatWrapperSerializer()); 100 | 101 | serializers.put(double.class, new DoubleSerializer()); 102 | serializers.put(double[].class, new DoubleArraySerializer()); 103 | serializers.put(double[][].class, new Double2DArraySerializer()); 104 | serializers.put(Double.class, new DoubleWrapperSerializer()); 105 | 106 | serializers.put(String.class, new StringSerializer()); 107 | serializers.put(String[].class, new StringArraySerializer()); 108 | serializers.put(String[][].class, new String2DArraySerializer()); 109 | serializers.put(StringBuffer.class, new StringBufferSerializer()); 110 | serializers.put(StringBuilder.class, new StringBuilderSerializer()); 111 | 112 | serializers.put(Date.class, new DateSerializer()); 113 | serializers.put(Enum.class, new EnumSerializer()); 114 | } 115 | 116 | 117 | private void buildDeserializers() { 118 | deserializers.put(int.class, new IntDeserializer()); 119 | deserializers.put(int[].class, new IntArrayDeserializer()); 120 | deserializers.put(int[][].class, new Int2DArrayDeserializer()); 121 | deserializers.put(Integer.class, new IntegerDeserializer()); 122 | deserializers.put(BigInteger.class, new BigIntegerDeserializer()); 123 | 124 | deserializers.put(long.class, new LongDeserializer()); 125 | deserializers.put(long[].class, new LongArrayDeserializer()); 126 | deserializers.put(long[][].class, new Long2DArrayDeserializer()); 127 | deserializers.put(Long.class, new LongWrapperDeserializer()); 128 | 129 | deserializers.put(short.class, new ShortDeserializer()); 130 | deserializers.put(short[].class, new ShortArrayDeserializer()); 131 | deserializers.put(short[][].class, new Short2DArrayDeserializer()); 132 | deserializers.put(Short.class, new ShortWrapperDeserializer()); 133 | 134 | deserializers.put(byte.class, new ByteDeserializer()); 135 | deserializers.put(byte[].class, new ByteArrayDeserializer()); 136 | deserializers.put(byte[][].class, new Byte2DArrayDeserializer()); 137 | deserializers.put(Byte.class, new ByteWrapperDeserializer()); 138 | 139 | deserializers.put(char.class, new CharDeserializer()); 140 | deserializers.put(char[].class, new CharArrayDeserializer()); 141 | deserializers.put(char[][].class, new Char2DArrayDeserializer()); 142 | deserializers.put(Character.class, new CharacterDeserializer()); 143 | 144 | deserializers.put(boolean.class, new BooleanDeserializer()); 145 | deserializers.put(boolean[].class, new BooleanArrayDeserializer()); 146 | deserializers.put(boolean[][].class, new Boolean2DArrayDeserializer()); 147 | deserializers.put(Boolean.class, new BooleanWrapperDeserializer()); 148 | 149 | deserializers.put(float.class, new FloatDeserializer()); 150 | deserializers.put(float[].class, new FloatArrayDeserializer()); 151 | deserializers.put(float[][].class, new Float2DArrayDeserializer()); 152 | deserializers.put(Float.class, new FloatWrapperDeserializer()); 153 | 154 | deserializers.put(double.class, new DoubleDeserializer()); 155 | deserializers.put(double[].class, new DoubleArrayDeserializer()); 156 | deserializers.put(double[][].class, new Double2DArrayDeserializer()); 157 | deserializers.put(Double.class, new DoubleWrapperDeserializer()); 158 | 159 | deserializers.put(String.class, new StringDeserializer()); 160 | deserializers.put(String[].class, new StringArrayDeserializer()); 161 | deserializers.put(String[][].class, new String2DArrayDeserializer()); 162 | deserializers.put(StringBuffer.class, new StringBufferDeserializer()); 163 | deserializers.put(StringBuilder.class, new StringBuilderDeserializer()); 164 | 165 | deserializers.put(Date.class, new DateDeserializer()); 166 | } 167 | 168 | } 169 | 170 | /** 171 | * 172 | */ 173 | static class VolatileTypeRepository extends TypeRepository { 174 | 175 | private final Map serializers = new HashMap<>(32); 176 | private final Map deserializers = new HashMap<>(32); 177 | 178 | VolatileTypeRepository() { 179 | buildVolatileSerializers(); 180 | buildVolatileDeserializers(); 181 | } 182 | 183 | @Override 184 | public Serializer getSerializer(Class type) { 185 | return serializers.get(type); 186 | } 187 | 188 | @Override 189 | public Deserializer getDeserializer(Class type) { 190 | return deserializers.get(type); 191 | } 192 | 193 | @Override 194 | public boolean serializerDeserializerExistsFor(Class type) { 195 | return serializers.containsKey(type) && deserializers.containsKey(type); 196 | } 197 | 198 | private void buildVolatileSerializers() { 199 | serializers.put(int.class, new IntVolatileSerializer()); 200 | serializers.put(int[].class, new IntArrayVolatileSerializer()); 201 | serializers.put(int[][].class, new Int2DArrayVolatileSerializer()); 202 | serializers.put(Integer.class, new IntegerVolatileSerializer()); 203 | serializers.put(BigInteger.class, new BigIntegerVolatileSerializer()); 204 | 205 | serializers.put(long.class, new LongVolatileSerializer()); 206 | serializers.put(long[].class, new LongArrayVolatileSerializer()); 207 | serializers.put(long[][].class, new Long2DArrayVolatileSerializer()); 208 | serializers.put(Long.class, new LongWrapperVolatileSerializer()); 209 | 210 | serializers.put(short.class, new ShortVolatileSerializer()); 211 | serializers.put(short[].class, new ShortArrayVolatileSerializer()); 212 | serializers.put(short[][].class, new Short2DArrayVolatileSerializer()); 213 | serializers.put(Short.class, new ShortWrapperVolatileSerializer()); 214 | 215 | serializers.put(byte.class, new ByteVolatileSerializer()); 216 | serializers.put(byte[].class, new ByteArrayVolatileSerializer()); 217 | serializers.put(byte[][].class, new Byte2DArrayVolatileSerializer()); 218 | serializers.put(Byte.class, new ByteWrapperVolatileSerializer()); 219 | 220 | serializers.put(char.class, new CharVolatileSerializer()); 221 | serializers.put(char[].class, new CharArrayVolatileSerializer()); 222 | serializers.put(char[][].class, new Char2DArrayVolatileSerializer()); 223 | serializers.put(Character.class, new CharacterVolatileSerializer()); 224 | 225 | serializers.put(boolean.class, new BooleanVolatileSerializer()); 226 | serializers.put(boolean[].class, new BooleanArrayVolatileSerializer()); 227 | serializers.put(boolean[][].class, new Boolean2DArrayVolatileSerializer()); 228 | serializers.put(Boolean.class, new BooleanWrapperVolatileSerializer()); 229 | 230 | serializers.put(float.class, new FloatVolatileSerializer()); 231 | serializers.put(float[].class, new FloatArrayVolatileSerializer()); 232 | serializers.put(float[][].class, new Float2DArrayVolatileSerializer()); 233 | serializers.put(Float.class, new FloatWrapperVolatileSerializer()); 234 | 235 | serializers.put(double.class, new DoubleVolatileSerializer()); 236 | serializers.put(double[].class, new DoubleArrayVolatileSerializer()); 237 | serializers.put(double[][].class, new Double2DArrayVolatileSerializer()); 238 | serializers.put(Double.class, new DoubleWrapperVolatileSerializer()); 239 | 240 | serializers.put(String.class, new StringVolatileSerializer()); 241 | serializers.put(String[].class, new StringArrayVolatileSerializer()); 242 | serializers.put(String[][].class, new String2DArrayVolatileSerializer()); 243 | serializers.put(StringBuffer.class, new StringBufferVolatileSerializer()); 244 | serializers.put(StringBuilder.class, new StringBuilderVolatileSerializer()); 245 | 246 | serializers.put(Enum.class, new EnumVolatileSerializer()); 247 | } 248 | 249 | private void buildVolatileDeserializers() { 250 | deserializers.put(int.class, new IntVolatileDeserializer()); 251 | deserializers.put(int[].class, new IntArrayVolatileDeserializer()); 252 | deserializers.put(int[][].class, new Int2DArrayVolatileDeserializer()); 253 | deserializers.put(Integer.class, new IntegerVolatileDeserializer()); 254 | deserializers.put(BigInteger.class, new BigIntegerVolatileDeserializer()); 255 | 256 | deserializers.put(long.class, new LongVolatileDeserializer()); 257 | deserializers.put(long[].class, new LongArrayVolatileDeserializer()); 258 | deserializers.put(long[][].class, new Long2DArrayVolatileDeserializer()); 259 | deserializers.put(Long.class, new LongWrapperVolatileDeserializer()); 260 | 261 | deserializers.put(short.class, new ShortVolatileDeserializer()); 262 | deserializers.put(short[].class, new ShortArrayVolatileDeserializer()); 263 | deserializers.put(short[][].class, new Short2DArrayVolatileDeserializer()); 264 | deserializers.put(Short.class, new ShortWrapperVolatileDeserializer()); 265 | 266 | deserializers.put(byte.class, new ByteVolatileDeserializer()); 267 | deserializers.put(byte[].class, new ByteArrayVolatileDeserializer()); 268 | deserializers.put(byte[][].class, new Byte2DArrayVolatileDeserializer()); 269 | deserializers.put(Byte.class, new ByteWrapperVolatileDeserializer()); 270 | 271 | deserializers.put(char.class, new CharVolatileDeserializer()); 272 | deserializers.put(char[].class, new CharArrayVolatileDeserializer()); 273 | deserializers.put(char[][].class, new Char2DArrayVolatileDeserializer()); 274 | deserializers.put(Character.class, new CharacterVolatileDeserializer()); 275 | 276 | deserializers.put(boolean.class, new BooleanVolatileDeserializer()); 277 | deserializers.put(boolean[].class, new BooleanArrayVolatileDeserializer()); 278 | deserializers.put(boolean[][].class, new Boolean2DArrayVolatileDeserializer()); 279 | deserializers.put(Boolean.class, new BooleanWrapperVolatileDeserializer()); 280 | 281 | deserializers.put(float.class, new FloatVolatileDeserializer()); 282 | deserializers.put(float[].class, new FloatArrayVolatileDeserializer()); 283 | deserializers.put(float[][].class, new Float2DArrayVolatileDeserializer()); 284 | deserializers.put(Float.class, new FloatWrapperVolatileDeserializer()); 285 | 286 | deserializers.put(double.class, new DoubleVolatileDeserializer()); 287 | deserializers.put(double[].class, new DoubleArrayVolatileDeserializer()); 288 | deserializers.put(double[][].class, new Double2DArrayVolatileDeserializer()); 289 | deserializers.put(Double.class, new DoubleWrapperVolatileDeserializer()); 290 | 291 | deserializers.put(String.class, new StringVolatileDeserializer()); 292 | deserializers.put(String[].class, new StringArrayVolatileDeserializer()); 293 | deserializers.put(String[][].class, new String2DArrayVolatileDeserializer()); 294 | deserializers.put(StringBuffer.class, new StringBufferVolatileDeserializer()); 295 | deserializers.put(StringBuilder.class, new StringBuilderVolatileDeserializer()); 296 | 297 | } 298 | 299 | } 300 | 301 | 302 | 303 | } 304 | -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/UnknownRegisteredHashCode.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | public class UnknownRegisteredHashCode extends RuntimeException { 4 | } 5 | -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/UnknownRegisteredTypeException.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | public class UnknownRegisteredTypeException extends RuntimeException { 4 | 5 | public UnknownRegisteredTypeException(String name) { 6 | super("Did not find a registered type for class '" + name + "'. Did you forget to register the class?"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /blixtser-core/src/main/java/com/mojang/blixtser/core/UnsafeMemory.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import static com.mojang.blixtser.core.ClassSchemaBuilder.stringClassInfo; 4 | import static com.mojang.blixtser.core.SerializationUtils.unsafe; 5 | 6 | public class UnsafeMemory { 7 | 8 | private static final int INITIAL_CAPACITY = 1024; 9 | 10 | private static final long byteArrayOffset = unsafe.arrayBaseOffset(byte[].class); 11 | private static final long shortArrayOffset = unsafe.arrayBaseOffset(short[].class); 12 | private static final long intArrayOffset = unsafe.arrayBaseOffset(int[].class); 13 | private static final long charArrayOffset = unsafe.arrayBaseOffset(char[].class); 14 | private static final long floatArrayOffset = unsafe.arrayBaseOffset(float[].class); 15 | private static final long longArrayOffset = unsafe.arrayBaseOffset(long[].class); 16 | private static final long doubleArrayOffset = unsafe.arrayBaseOffset(double[].class); 17 | private static final long booleanArrayOffset = unsafe.arrayBaseOffset(boolean[].class); 18 | 19 | private static final int SIZE_OF_LONG = 8; 20 | private static final int SIZE_OF_DOUBLE = 8; 21 | private static final int SIZE_OF_INT = 4; 22 | private static final int SIZE_OF_FLOAT = 4; 23 | private static final int SIZE_OF_CHAR = 2; 24 | private static final int SIZE_OF_SHORT = 2; 25 | private static final int SIZE_OF_BOOLEAN = 1; 26 | private static final int SIZE_OF_BYTE = 1; 27 | 28 | private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 29 | 30 | private int pos = 0; 31 | private byte[] buffer; 32 | 33 | public UnsafeMemory(final byte[] buffer) { 34 | if (null == buffer) { 35 | throw new NullPointerException("buffer cannot be null"); 36 | } 37 | 38 | this.buffer = buffer; 39 | } 40 | 41 | public UnsafeMemory() { 42 | this.buffer = new byte[INITIAL_CAPACITY]; 43 | } 44 | 45 | public final void reset() { 46 | pos = 0; 47 | } 48 | 49 | public final int getPos() { 50 | return pos; 51 | } 52 | 53 | public final void writeByte(final byte value) { 54 | ensureCapacity(SIZE_OF_BYTE); 55 | unsafe.putByte(buffer, byteArrayOffset + pos, value); 56 | pos += SIZE_OF_BYTE; 57 | } 58 | 59 | public final byte readByte() { 60 | byte value = unsafe.getByte(buffer, byteArrayOffset + pos); 61 | pos += SIZE_OF_BYTE; 62 | 63 | return value; 64 | } 65 | 66 | public final void writeShort(final short value) { 67 | ensureCapacity(SIZE_OF_SHORT); 68 | unsafe.putShort(buffer, byteArrayOffset + pos, value); 69 | pos += SIZE_OF_SHORT; 70 | } 71 | 72 | public final short readShort() { 73 | short value = unsafe.getShort(buffer, byteArrayOffset + pos); 74 | pos += SIZE_OF_SHORT; 75 | 76 | return value; 77 | } 78 | 79 | public final void writeBoolean(final boolean value) { 80 | ensureCapacity(SIZE_OF_BOOLEAN); 81 | unsafe.putBoolean(buffer, byteArrayOffset + pos, value); 82 | pos += SIZE_OF_BOOLEAN; 83 | } 84 | 85 | public final boolean readBoolean() { 86 | boolean value = unsafe.getBoolean(buffer, byteArrayOffset + pos); 87 | pos += SIZE_OF_BOOLEAN; 88 | 89 | return value; 90 | } 91 | 92 | public final void writeInt(final int value) { 93 | ensureCapacity(SIZE_OF_INT); 94 | unsafe.putInt(buffer, byteArrayOffset + pos, value); 95 | pos += SIZE_OF_INT; 96 | } 97 | 98 | public final int readInt() { 99 | int value = unsafe.getInt(buffer, byteArrayOffset + pos); 100 | pos += SIZE_OF_INT; 101 | 102 | return value; 103 | } 104 | 105 | public final void writeLong(final long value) { 106 | ensureCapacity(SIZE_OF_LONG); 107 | unsafe.putLong(buffer, byteArrayOffset + pos, value); 108 | pos += SIZE_OF_LONG; 109 | } 110 | 111 | public final long readLong() { 112 | long value = unsafe.getLong(buffer, byteArrayOffset + pos); 113 | pos += SIZE_OF_LONG; 114 | 115 | return value; 116 | } 117 | 118 | public final void writeDouble(final double value) { 119 | ensureCapacity(SIZE_OF_DOUBLE); 120 | unsafe.putDouble(buffer, byteArrayOffset + pos, value); 121 | pos += SIZE_OF_DOUBLE; 122 | } 123 | 124 | public final double readDouble() { 125 | double value = unsafe.getDouble(buffer, byteArrayOffset + pos); 126 | pos += SIZE_OF_DOUBLE; 127 | 128 | return value; 129 | } 130 | 131 | public final void writeFloat(final float value) { 132 | ensureCapacity(SIZE_OF_FLOAT); 133 | unsafe.putFloat(buffer, byteArrayOffset + pos, value); 134 | pos += SIZE_OF_FLOAT; 135 | } 136 | 137 | public final float readFloat() { 138 | float value = unsafe.getFloat(buffer, byteArrayOffset + pos); 139 | pos += SIZE_OF_FLOAT; 140 | 141 | return value; 142 | } 143 | 144 | public final void writeString(final String value) { 145 | for (ClassSchemaBuilder.FieldInfo fi : stringClassInfo.fieldInfos) { 146 | fi.serialize(this, value); 147 | } 148 | } 149 | 150 | public final String readString() { 151 | String object = new String(); 152 | for (ClassSchemaBuilder.FieldInfo fi : stringClassInfo.fieldInfos) { 153 | fi.deserialize(this, object); 154 | } 155 | return object; 156 | } 157 | 158 | public final void writeChar(final char value) { 159 | ensureCapacity(SIZE_OF_CHAR); 160 | unsafe.putChar(buffer, byteArrayOffset + pos, value); 161 | pos += SIZE_OF_CHAR; 162 | } 163 | 164 | public final char readChar() { 165 | char value = unsafe.getChar(buffer, byteArrayOffset + pos); 166 | pos += SIZE_OF_CHAR; 167 | 168 | return value; 169 | } 170 | 171 | public final void writeInteger(final Integer value) { 172 | ensureCapacity(SIZE_OF_INT + 1); 173 | if (writeNullable(value)) { 174 | writeInt(value); 175 | } 176 | } 177 | 178 | public final void writeLongWrapper(final Long value) { 179 | ensureCapacity(SIZE_OF_LONG + 1); 180 | if (writeNullable(value)) { 181 | writeLong(value); 182 | } 183 | } 184 | 185 | public final void writeFloatWrapper(final Float value) { 186 | ensureCapacity(SIZE_OF_FLOAT + 1); 187 | if (writeNullable(value)) { 188 | writeFloat(value); 189 | } 190 | } 191 | 192 | public final void writeDoubleWrapper(final Double value) { 193 | ensureCapacity(SIZE_OF_DOUBLE + 1); 194 | if (writeNullable(value)) { 195 | writeDouble(value); 196 | } 197 | } 198 | 199 | public final void writeShortWrapper(final Short value) { 200 | ensureCapacity(SIZE_OF_SHORT); 201 | if (writeNullable(value)) { 202 | writeShort(value); 203 | } 204 | } 205 | 206 | public final void writeBooleanWrapper(final Boolean value) { 207 | ensureCapacity(SIZE_OF_BOOLEAN + 1); 208 | if (writeNullable(value)) { 209 | writeBoolean(value); 210 | } 211 | } 212 | 213 | public final void writeCharacter(final Character value) { 214 | ensureCapacity(SIZE_OF_CHAR + 1); 215 | if (writeNullable(value)) { 216 | writeChar(value); 217 | } 218 | } 219 | 220 | public final void writeByteWrapper(final Byte value) { 221 | ensureCapacity(SIZE_OF_BYTE + 1); 222 | if (writeNullable(value)) { 223 | writeByte(value); 224 | } 225 | } 226 | 227 | public final Integer readInteger() { 228 | return readByte() == 0 ? null : readInt(); 229 | } 230 | 231 | public final Long readLongWrapper() { 232 | return readByte() == 0 ? null : readLong(); 233 | } 234 | 235 | public final Short readShortWrapper() { 236 | return readByte() == 0 ? null : readShort(); 237 | } 238 | 239 | public final Boolean readBooleanWrapper() { 240 | return readByte() == 0 ? null : readBoolean(); 241 | } 242 | 243 | public final Character readCharacter() { 244 | return readByte() == 0 ? null : readChar(); 245 | } 246 | 247 | public final Float readFloatWrapper() { 248 | return readByte() == 0 ? null : readFloat(); 249 | } 250 | 251 | public final Double readDoubleWrapper() { 252 | return readByte() == 0 ? null : readDouble(); 253 | } 254 | 255 | public final Byte readByteWrapper() { 256 | return readByte() == 0 ? null : readByte(); 257 | } 258 | 259 | public final byte[] getBuffer() { 260 | byte[] usedBuffer = new byte[pos]; 261 | 262 | unsafe.copyMemory(buffer, byteArrayOffset, usedBuffer, byteArrayOffset, pos); 263 | 264 | return usedBuffer; 265 | } 266 | 267 | public final void writeCharArray(final char[] values) { 268 | ensureCapacity(SIZE_OF_INT); 269 | if (writeNullable(values)) { 270 | writeInt(values.length); 271 | writeGenericArray(values.length << 1, charArrayOffset, values); 272 | } 273 | } 274 | 275 | public final void writeByteArray(final byte[] values) { 276 | ensureCapacity(SIZE_OF_INT); 277 | if (writeNullable(values)) { 278 | writeInt(values.length); 279 | writeGenericArray(values.length, byteArrayOffset, values); 280 | } 281 | } 282 | 283 | public final void writeLongArray(final long[] values) { 284 | ensureCapacity(SIZE_OF_INT); 285 | if (writeNullable(values)) { 286 | writeInt(values.length); 287 | writeGenericArray(values.length << 3, longArrayOffset, values); 288 | } 289 | } 290 | 291 | public final void writeDoubleArray(final double[] values) { 292 | ensureCapacity(SIZE_OF_INT); 293 | if (writeNullable(values)) { 294 | writeInt(values.length); 295 | writeGenericArray(values.length << 3, doubleArrayOffset, values); 296 | } 297 | } 298 | 299 | public final void writeFloatArray(final float[] values) { 300 | ensureCapacity(SIZE_OF_INT); 301 | if (writeNullable(values)) { 302 | writeInt(values.length); 303 | writeGenericArray(values.length << 2, floatArrayOffset, values); 304 | } 305 | } 306 | 307 | public final void writeIntArray(final int[] values) { 308 | ensureCapacity(SIZE_OF_INT); 309 | if (writeNullable(values)) { 310 | writeInt(values.length); 311 | writeGenericArray(values.length << 2, intArrayOffset, values); 312 | } 313 | } 314 | 315 | public final void writeShortArray(final short[] values) { 316 | ensureCapacity(SIZE_OF_INT); 317 | if (writeNullable(values)) { 318 | writeInt(values.length); 319 | writeGenericArray(values.length << 1, shortArrayOffset, values); 320 | } 321 | } 322 | 323 | public final void writeBooleanArray(final boolean[] values) { 324 | ensureCapacity(SIZE_OF_INT); 325 | if (writeNullable(values)) { 326 | writeInt(values.length); 327 | writeGenericArray(values.length, booleanArrayOffset, values); 328 | } 329 | } 330 | 331 | public final char[] readCharArray() { 332 | if (readNullable()) { 333 | char[] values = new char[readInt()]; 334 | readAnArray(values.length << 1, charArrayOffset, values); 335 | return values; 336 | } 337 | return null; 338 | } 339 | 340 | public final byte[] readByteArray() { 341 | if (readNullable()) { 342 | byte[] values = new byte[readInt()]; 343 | readAnArray(values.length, byteArrayOffset, values); 344 | return values; 345 | } 346 | return null; 347 | } 348 | 349 | public final int[] readIntArray() { 350 | if (readNullable()) { 351 | int[] values = new int[readInt()]; 352 | readAnArray(values.length << 2, intArrayOffset, values); 353 | return values; 354 | } 355 | return null; 356 | } 357 | 358 | public final long[] readLongArray() { 359 | if (readNullable()) { 360 | long[] values = new long[readInt()]; 361 | readAnArray(values.length << 3, longArrayOffset, values); 362 | return values; 363 | } 364 | return null; 365 | } 366 | 367 | public final double[] readDoubleArray() { 368 | if (readNullable()) { 369 | double[] values = new double[readInt()]; 370 | readAnArray(values.length << 3, doubleArrayOffset, values); 371 | return values; 372 | } 373 | return null; 374 | } 375 | 376 | public final float[] readFloatArray() { 377 | if (readNullable()) { 378 | float[] values = new float[readInt()]; 379 | readAnArray(values.length << 2, floatArrayOffset, values); 380 | return values; 381 | } 382 | return null; 383 | } 384 | 385 | public final short[] readShortArray() { 386 | if (readNullable()) { 387 | short[] values = new short[readInt()]; 388 | readAnArray(values.length << 1, shortArrayOffset, values); 389 | return values; 390 | } 391 | return null; 392 | } 393 | 394 | public final boolean[] readBooleanArray() { 395 | if (readNullable()) { 396 | boolean[] values = new boolean[readInt()]; 397 | readAnArray(values.length, booleanArrayOffset, values); 398 | return values; 399 | } 400 | return null; 401 | } 402 | 403 | public final void writeGenericArray(long bytesToCopy, long arrayOffset, Object values) { 404 | ensureCapacity(bytesToCopy); 405 | unsafe.copyMemory(values, arrayOffset, buffer, byteArrayOffset + pos, bytesToCopy); 406 | pos += bytesToCopy; 407 | } 408 | 409 | private void readAnArray(long bytesToCopy, long arrayOffset, Object values) { 410 | unsafe.copyMemory(buffer, byteArrayOffset + pos, values, arrayOffset, bytesToCopy); 411 | pos += bytesToCopy; 412 | } 413 | 414 | private boolean writeNullable(final Object value) { 415 | if (value != null) { 416 | writeByte((byte) 1); 417 | return true; 418 | } else { 419 | writeByte((byte) 0); 420 | return false; 421 | } 422 | } 423 | 424 | private boolean readNullable() { 425 | return readByte() != 0; 426 | } 427 | 428 | public final void writeBatch(Object object, long offset, int size) { 429 | ensureCapacity(size); 430 | unsafe.copyMemory(object, offset, buffer, byteArrayOffset + pos, size); 431 | pos += size; 432 | } 433 | 434 | public final void readBatch(Object object, long offset, int size) { 435 | long off = offset; 436 | 437 | while (size >= SIZE_OF_LONG) { 438 | unsafe.putLong(object, off, readLong()); 439 | off += SIZE_OF_LONG; 440 | size -= SIZE_OF_LONG; 441 | } 442 | 443 | if (size >= SIZE_OF_INT) { 444 | unsafe.putInt(object, off, readInt()); 445 | off += SIZE_OF_INT; 446 | size -= SIZE_OF_INT; 447 | } 448 | 449 | if (size >= SIZE_OF_CHAR) { 450 | unsafe.putChar(object, off, readChar()); 451 | off += SIZE_OF_CHAR; 452 | } 453 | 454 | if (size % 2 > 0) { 455 | unsafe.putByte(object, off, readByte()); 456 | } 457 | 458 | } 459 | 460 | private void ensureCapacity(long minCapacity) { 461 | if (buffer.length - pos > minCapacity) { 462 | // there is enough space left in the buffer 463 | return; 464 | } 465 | 466 | int oldCapacity = buffer.length; 467 | int newCapacity = oldCapacity + (oldCapacity >> 1); 468 | if (newCapacity - MAX_ARRAY_SIZE > 0) { 469 | throw new OutOfMemoryError("Could not allocate more than " + MAX_ARRAY_SIZE + " bytes for UnsafeMemory"); 470 | } 471 | 472 | byte[] newBuffer = new byte[newCapacity]; 473 | 474 | unsafe.copyMemory(buffer, byteArrayOffset, newBuffer, byteArrayOffset, buffer.length); 475 | buffer = newBuffer; 476 | } 477 | 478 | } 479 | -------------------------------------------------------------------------------- /blixtser-core/src/test/java/com/mojang/blixtser/core/BlixtserTest.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.math.BigInteger; 7 | import java.util.Calendar; 8 | import java.util.Date; 9 | 10 | import static com.mojang.blixtser.core.TestClasses.*; 11 | 12 | public class BlixtserTest { 13 | 14 | private Blixtser blixtser = new Blixtser(); 15 | 16 | public BlixtserTest() { 17 | for (Class c : TestClasses.class.getClasses()) { 18 | blixtser.register(c); 19 | } 20 | } 21 | 22 | @Test 23 | public void test_primitive_int() { 24 | int a = 16; 25 | IntPrimitiveTestClass testClass = new IntPrimitiveTestClass(a, a); 26 | 27 | testSerializationFor(testClass); 28 | } 29 | 30 | @Test 31 | public void test_primitive_long() { 32 | long a = 162434234234211l; 33 | LongPrimitiveTestClass testClass = new LongPrimitiveTestClass(a, a); 34 | 35 | testSerializationFor(testClass); 36 | } 37 | 38 | @Test 39 | public void test_primitive_double() { 40 | double a = 162434234.2323d; 41 | DoublePrimitiveTestClass testClass = new DoublePrimitiveTestClass(a, a); 42 | 43 | testSerializationFor(testClass); 44 | } 45 | 46 | @Test 47 | public void test_primitive_float() { 48 | float a = 162434234.2323f; 49 | FloatPrimitiveTestClass testClass = new FloatPrimitiveTestClass(a, a); 50 | 51 | testSerializationFor(testClass); 52 | } 53 | 54 | @Test 55 | public void test_primitive_char() { 56 | char a = '形'; 57 | CharPrimitiveTestClass testClass = new CharPrimitiveTestClass(a, a); 58 | 59 | testSerializationFor(testClass); 60 | } 61 | 62 | @Test 63 | public void test_primitive_short() { 64 | short a = 12; 65 | ShortPrimitiveTestClass testClass = new ShortPrimitiveTestClass(a, a); 66 | 67 | testSerializationFor(testClass); 68 | } 69 | 70 | @Test 71 | public void test_primitive_byte() { 72 | byte a = 0x12; 73 | BytePrimitiveTestClass testClass = new BytePrimitiveTestClass(a, a); 74 | 75 | testSerializationFor(testClass); 76 | } 77 | 78 | @Test 79 | public void test_primitive_boolean() { 80 | boolean a = true; 81 | BooleanPrimitiveTestClass testClass = new BooleanPrimitiveTestClass(a, a); 82 | 83 | testSerializationFor(testClass); 84 | } 85 | 86 | @Test 87 | public void test_enum() { 88 | EnumTestClass.SomeEnum a = EnumTestClass.SomeEnum.B; 89 | EnumTestClass testClass = new EnumTestClass(a, a); 90 | 91 | testSerializationFor(testClass); 92 | } 93 | 94 | @Test 95 | public void test_string() { 96 | String a = "Ämir & Daniel"; 97 | String b = "Ämir & Daniel"; 98 | StringTestClass testClass = new StringTestClass(a, b); 99 | 100 | testSerializationFor(testClass); 101 | 102 | testClass.setA(null); 103 | testClass.setB(null); 104 | 105 | testSerializationFor(testClass); 106 | } 107 | 108 | @Test 109 | public void test_non_primitive_int() { 110 | Integer a = 1615; 111 | Integer b = 1716; 112 | IntNonPrimitiveTestClass testClass = new IntNonPrimitiveTestClass(a, b); 113 | 114 | testSerializationFor(testClass); 115 | 116 | testClass.setA(null); 117 | testClass.setB(null); 118 | 119 | testSerializationFor(testClass); 120 | } 121 | 122 | @Test 123 | public void test_non_primitive_long() { 124 | Long a = 1615123l; 125 | Long b = 1615123l; 126 | LongNonPrimitiveTestClass testClass = new LongNonPrimitiveTestClass(a, b); 127 | 128 | testSerializationFor(testClass); 129 | 130 | testClass.setA(null); 131 | testClass.setB(null); 132 | 133 | testSerializationFor(testClass); 134 | } 135 | 136 | @Test 137 | public void test_non_primitive_double() { 138 | Double a = 1615123.23d; 139 | Double b = 1615123.23d; 140 | DoubleNonPrimitiveTestClass testClass = new DoubleNonPrimitiveTestClass(a, b); 141 | 142 | testSerializationFor(testClass); 143 | 144 | testClass.setA(null); 145 | testClass.setB(null); 146 | 147 | testSerializationFor(testClass); 148 | } 149 | 150 | @Test 151 | public void test_non_primitive_float() { 152 | Float a = 1615123.23f; 153 | Float b = 1615123.23f; 154 | FloatNonPrimitiveTestClass testClass = new FloatNonPrimitiveTestClass(a, b); 155 | 156 | testSerializationFor(testClass); 157 | 158 | testClass.setA(null); 159 | testClass.setB(null); 160 | 161 | testSerializationFor(testClass); 162 | } 163 | 164 | @Test 165 | public void test_non_primitive_char() { 166 | Character a = 'Ä'; 167 | Character b = 'Ö'; 168 | CharNonPrimitiveTestClass testClass = new CharNonPrimitiveTestClass(a, b); 169 | 170 | testSerializationFor(testClass); 171 | 172 | testClass.setA(null); 173 | testClass.setB(null); 174 | 175 | testSerializationFor(testClass); 176 | } 177 | 178 | @Test 179 | public void test_non_primitive_short() { 180 | Short a = 12; 181 | Short b = 12; 182 | ShortNonPrimitiveTestClass testClass = new ShortNonPrimitiveTestClass(a, b); 183 | 184 | testSerializationFor(testClass); 185 | 186 | testClass.setA(null); 187 | testClass.setB(null); 188 | 189 | testSerializationFor(testClass); 190 | } 191 | 192 | @Test 193 | public void test_non_primitive_byte() { 194 | Byte a = 0x12; 195 | Byte b = 0x13; 196 | ByteNonPrimitiveTestClass testClass = new ByteNonPrimitiveTestClass(a, b); 197 | 198 | testSerializationFor(testClass); 199 | 200 | testClass.setA(null); 201 | testClass.setB(null); 202 | 203 | testSerializationFor(testClass); 204 | } 205 | 206 | @Test 207 | public void test_non_primitive_boolean() { 208 | BooleanNonPrimitiveTestClass testClass = new BooleanNonPrimitiveTestClass(true, true); 209 | 210 | testSerializationFor(testClass); 211 | 212 | testClass.setA(null); 213 | testClass.setB(null); 214 | 215 | testSerializationFor(testClass); 216 | } 217 | 218 | @Test 219 | public void test_string_builder() { 220 | StringBuilder a = new StringBuilder(); 221 | a.append("Ämir & Daniel"); 222 | 223 | StringBuilder b = new StringBuilder(); 224 | b.append("Ämir & Daniel"); 225 | 226 | StringBuilderTestClass testClass = new StringBuilderTestClass(a, b); 227 | 228 | testSerializationFor(testClass); 229 | 230 | testClass.setA(null); 231 | testClass.setB(null); 232 | testSerializationFor(testClass); 233 | 234 | } 235 | 236 | @Test 237 | public void test_string_buffer() { 238 | StringBuffer a = new StringBuffer(); 239 | a.append("Ämir & Daniel"); 240 | 241 | StringBuffer b = new StringBuffer(); 242 | b.append("Ämir & Daniel"); 243 | 244 | StringBufferTestClass testClass = new StringBufferTestClass(a, b); 245 | 246 | testSerializationFor(testClass); 247 | 248 | testClass.setA(null); 249 | testClass.setB(null); 250 | testSerializationFor(testClass); 251 | 252 | } 253 | 254 | @Test 255 | public void test_primitive_int_array() { 256 | int[] a = new int[] {1, 2, 3, 4, 5, 6}; 257 | int[] b = new int[] {1, 2, 3, 4, 5, 6}; 258 | IntPrimitiveArrayTestClass testClass = new IntPrimitiveArrayTestClass(a, b); 259 | 260 | testSerializationFor(testClass); 261 | 262 | testClass.setA(null); 263 | testClass.setB(null); 264 | 265 | testSerializationFor(testClass); 266 | } 267 | 268 | @Test 269 | public void test_primitive_int_2d_array() { 270 | int[][] a = new int[][] { new int[]{1, 2}, new int[]{3, 4}, new int[]{5, 6} }; 271 | int[][] b = new int[][] { new int[]{1, 2}, new int[]{3, 4}, new int[]{5, 6}, null }; 272 | IntPrimitive2DArrayTestClass testClass = new IntPrimitive2DArrayTestClass(a, b); 273 | 274 | testSerializationFor(testClass); 275 | 276 | testClass.setA(null); 277 | testClass.setB(null); 278 | testSerializationFor(testClass); 279 | } 280 | 281 | @Test 282 | public void test_primitive_long_array() { 283 | long[] a = new long[] {1l, 2l, 3l, 4l, 5l, 6l}; 284 | long[] b = new long[] {1l, 2l, 3l, 4l, 5l, 6l}; 285 | LongPrimitiveArrayTestClass testClass = new LongPrimitiveArrayTestClass(a, b); 286 | 287 | testSerializationFor(testClass); 288 | 289 | testClass.setA(null); 290 | testClass.setB(null); 291 | testSerializationFor(testClass); 292 | } 293 | 294 | @Test 295 | public void test_primitive_long_2d_array() { 296 | long[][] a = new long[][] {new long[]{1l}, null, new long[]{2l, 3l, 4l, 5l, 6l}}; 297 | long[][] b = new long[][] {new long[]{1l}, new long[]{2l, 3l, 4l, 5l, 6l}, null}; 298 | LongPrimitive2DArrayTestClass testClass = new LongPrimitive2DArrayTestClass(a, b); 299 | 300 | testSerializationFor(testClass); 301 | 302 | testClass.setA(null); 303 | testClass.setB(null); 304 | testSerializationFor(testClass); 305 | } 306 | 307 | @Test 308 | public void test_primitive_double_array() { 309 | double[] a = new double[] {1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; 310 | double[] b = new double[] {1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; 311 | DoublePrimitiveArrayTestClass testClass = new DoublePrimitiveArrayTestClass(a, b); 312 | 313 | testSerializationFor(testClass); 314 | 315 | testClass.setA(null); 316 | testClass.setB(null); 317 | testSerializationFor(testClass); 318 | } 319 | 320 | @Test 321 | public void test_primitive_double_2d_array() { 322 | double[][] a = new double[][] { new double[]{1.1, 2.2, 3.3}, new double[]{4.4, 5.5, 6.6}, null}; 323 | double[][] b = new double[][] { new double[]{1.1, 2.2, 3.3}, null, new double[]{4.4, 5.5, 6.6}}; 324 | DoublePrimitive2DArrayTestClass testClass = new DoublePrimitive2DArrayTestClass(a, b); 325 | 326 | testSerializationFor(testClass); 327 | 328 | testClass.setA(null); 329 | testClass.setB(null); 330 | testSerializationFor(testClass); 331 | } 332 | 333 | @Test 334 | public void test_primitive_float_array() { 335 | float[] a = new float[] {1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f}; 336 | float[] b = new float[] {1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f}; 337 | FloatPrimitiveArrayTestClass testClass = new FloatPrimitiveArrayTestClass(a, b); 338 | 339 | testSerializationFor(testClass); 340 | 341 | testClass.setA(null); 342 | testClass.setB(null); 343 | testSerializationFor(testClass); 344 | } 345 | 346 | @Test 347 | public void test_primitive_float_2d_array() { 348 | float[][] a = new float[][] { new float[]{1.1f, 2.2f, 3.3f}, null, new float[]{4.4f, 5.5f, 6.6f}}; 349 | float[][] b = new float[][] { new float[]{1.1f, 2.2f, 3.3f}, null, new float[]{4.4f, 5.5f, 6.6f}}; 350 | FloatPrimitive2DArrayTestClass testClass = new FloatPrimitive2DArrayTestClass(a, b); 351 | 352 | testSerializationFor(testClass); 353 | 354 | testClass.setA(null); 355 | testClass.setB(null); 356 | testSerializationFor(testClass); 357 | } 358 | 359 | @Test 360 | public void test_primitive_char_array() { 361 | char[] a = new char[] {'A', 'm', 'i', 'r'}; 362 | char[] b = new char[] {'A', 'm', 'i', 'r'}; 363 | CharPrimitiveArrayTestClass testClass = new CharPrimitiveArrayTestClass(a, b); 364 | 365 | testSerializationFor(testClass); 366 | 367 | testClass.setA(null); 368 | testClass.setB(null); 369 | testSerializationFor(testClass); 370 | } 371 | 372 | @Test 373 | public void test_primitive_char_2d_array() { 374 | char[][] a = new char[][] { new char[]{'A', 'm'}, null, new char[]{'i', 'r'}}; 375 | char[][] b = new char[][] { new char[]{'A', 'm'}, new char[]{'i', 'r'}, null}; 376 | CharPrimitive2DArrayTestClass testClass = new CharPrimitive2DArrayTestClass(a, b); 377 | 378 | testSerializationFor(testClass); 379 | 380 | testClass.setA(null); 381 | testClass.setB(null); 382 | testSerializationFor(testClass); 383 | } 384 | 385 | @Test 386 | public void test_primitive_short_array() { 387 | short[] a = new short[] {12, 13, 14, 15}; 388 | short[] b = new short[] {12, 13, 14, 15}; 389 | ShortPrimitiveArrayTestClass testClass = new ShortPrimitiveArrayTestClass(a, b); 390 | 391 | testSerializationFor(testClass); 392 | 393 | testClass.setA(null); 394 | testClass.setB(null); 395 | testSerializationFor(testClass); 396 | } 397 | 398 | @Test 399 | public void test_primitive_short_2d_array() { 400 | short[][] a = new short[][] { new short[]{12, 13}, null, new short[]{14, 15}}; 401 | short[][] b = new short[][] { new short[]{12, 13}, new short[]{14, 15}, null}; 402 | ShortPrimitive2DArrayTestClass testClass = new ShortPrimitive2DArrayTestClass(a, b); 403 | 404 | testSerializationFor(testClass); 405 | 406 | testClass.setA(null); 407 | testClass.setB(null); 408 | testSerializationFor(testClass); 409 | } 410 | 411 | @Test 412 | public void test_primitive_byte_array() { 413 | byte[] a = new byte[] {0x12, 0x13, 0x14, 0x15}; 414 | byte[] b = new byte[] {0x12, 0x13, 0x14, 0x15}; 415 | BytePrimitiveArrayTestClass testClass = new BytePrimitiveArrayTestClass(a, b); 416 | 417 | testSerializationFor(testClass); 418 | 419 | testClass.setA(null); 420 | testClass.setB(null); 421 | testSerializationFor(testClass); 422 | } 423 | 424 | @Test 425 | public void test_primitive_byte_2d_array() { 426 | byte[][] a = new byte[][] { new byte[]{0x12, 0x13}, null, new byte[]{0x14, 0x15}}; 427 | byte[][] b = new byte[][] { new byte[]{0x12, 0x13}, new byte[]{0x14, 0x15}, null}; 428 | BytePrimitive2DArrayTestClass testClass = new BytePrimitive2DArrayTestClass(a, b); 429 | 430 | testSerializationFor(testClass); 431 | 432 | testClass.setA(null); 433 | testClass.setB(null); 434 | testSerializationFor(testClass); 435 | } 436 | 437 | @Test 438 | public void test_primitive_boolean_array() { 439 | boolean[] a = new boolean[] {false, true, false, true}; 440 | boolean[] b = new boolean[] {false, true, false, true}; 441 | BooleanPrimitiveArrayTestClass testClass = new BooleanPrimitiveArrayTestClass(a, b); 442 | 443 | testSerializationFor(testClass); 444 | 445 | testClass.setA(null); 446 | testClass.setB(null); 447 | testSerializationFor(testClass); 448 | } 449 | 450 | @Test 451 | public void test_primitive_boolean_2d_array() { 452 | boolean[][] a = new boolean[][] { new boolean[]{false, true}, new boolean[]{false, true}}; 453 | boolean[][] b = new boolean[][] { new boolean[]{false, true}, new boolean[]{false, true}}; 454 | BooleanPrimitive2DArrayTestClass testClass = new BooleanPrimitive2DArrayTestClass(a, b); 455 | 456 | testSerializationFor(testClass); 457 | 458 | testClass.setA(null); 459 | testClass.setB(null); 460 | testSerializationFor(testClass); 461 | } 462 | 463 | @Test 464 | public void test_string_array() { 465 | String[] a = new String[] {"Ämir", "Daniel"}; 466 | String[] b = new String[] {"Ämir", "Daniel"}; 467 | StringArrayTestClass testClass = new StringArrayTestClass(a, b); 468 | 469 | testSerializationFor(testClass); 470 | 471 | testClass.setA(null); 472 | testClass.setB(null); 473 | 474 | testSerializationFor(testClass); 475 | } 476 | 477 | @Test 478 | public void test_string_2d_array() { 479 | String[][] a = new String[][] { new String[]{"Ämir", "Moulavi", null}, null, new String[]{"Daniel", "Frisk"}}; 480 | String[][] b = new String[][] { new String[]{"Ämir", "Moulavi", null}, null, new String[]{"Daniel", "Frisk"}}; 481 | String2DArrayTestClass testClass = new String2DArrayTestClass(a, b); 482 | 483 | testSerializationFor(testClass); 484 | 485 | testClass.setA(null); 486 | testClass.setB(null); 487 | 488 | testSerializationFor(testClass); 489 | } 490 | 491 | @Test 492 | public void test_date() { 493 | Date a = Calendar.getInstance().getTime(); 494 | DateTestClass testClass = new DateTestClass(); 495 | testClass.setA(a); 496 | 497 | testSerializationFor(testClass); 498 | 499 | testClass.setA(null); 500 | 501 | testSerializationFor(testClass); 502 | } 503 | 504 | @Test 505 | public void test_big_int() { 506 | BigInteger a = new BigInteger("124412"); 507 | BigIntegerTestClass testClass = new BigIntegerTestClass(); 508 | testClass.setA(a); 509 | 510 | testSerializationFor(testClass); 511 | } 512 | 513 | @Test 514 | public void test_serialization_deserialization() { 515 | SerializableClass serializableClass = SerializableClass.createAnObject(); 516 | byte[] serialized = blixtser.serialize(serializableClass); 517 | Object deserialized = blixtser.deserialize(serialized); 518 | 519 | Assert.assertTrue(serializableClass.equals(deserialized)); 520 | } 521 | 522 | @Test 523 | public void test_null_objects() { 524 | NullClass nullClass = new NullClass(); 525 | byte[] serialized = blixtser.serialize(nullClass); 526 | Object deserialized = blixtser.deserialize(serialized); 527 | 528 | Assert.assertTrue(nullClass.equals(deserialized)); 529 | } 530 | 531 | private void testSerializationFor(Object testClass) { 532 | byte[] serialized = blixtser.serialize(testClass); 533 | Object deserialized = blixtser.deserialize(serialized); 534 | 535 | Assert.assertTrue(testClass.equals(deserialized)); 536 | } 537 | 538 | } 539 | -------------------------------------------------------------------------------- /blixtser-core/src/test/java/com/mojang/blixtser/core/ClassSchemaBuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.util.List; 7 | 8 | public class ClassSchemaBuilderTest { 9 | 10 | private ClassSchemaBuilder classSchemaBuilder = new ClassSchemaBuilder(); 11 | 12 | @Test 13 | public void super_class() { 14 | ClassSchemaBuilder.ClassInfo classInfo = classSchemaBuilder.createClassInfo(TestClass.class); 15 | Assert.assertEquals(7, classInfo.fieldInfos.length); 16 | } 17 | 18 | @Test 19 | public void mergable_fields() { 20 | ClassSchemaBuilder.ClassInfo classInfo = classSchemaBuilder.createClassInfo(ClassWithMergeableFields1.class); 21 | Assert.assertEquals(1, classInfo.fieldInfos.length); 22 | } 23 | 24 | @Test 25 | public void mergable_fields_and_super_class() { 26 | ClassSchemaBuilder.ClassInfo classInfo = classSchemaBuilder.createClassInfo(ClassWithMergeableFields2.class); 27 | Assert.assertEquals(1, classInfo.fieldInfos.length); 28 | } 29 | 30 | @Test 31 | public void mergable_fields_and_super_class_and_volatile() { 32 | ClassSchemaBuilder.ClassInfo classInfo = classSchemaBuilder.createClassInfo(ClassWithMergeableFields3.class); 33 | Assert.assertEquals(4, classInfo.fieldInfos.length); 34 | } 35 | 36 | @Test 37 | public void unknown_fields() { 38 | ClassSchemaBuilder.ClassInfo classInfo = classSchemaBuilder.createClassInfo(ClassWithUnknownFieldTypes.class); 39 | Assert.assertEquals(2, classInfo.fieldInfos.length); 40 | } 41 | 42 | @Test 43 | public void abstract_class_test() { 44 | try { 45 | classSchemaBuilder.createClassInfo(AbstractClass.class); 46 | Assert.fail(); 47 | } catch (RuntimeException e) {} 48 | } 49 | 50 | @Test 51 | public void interface_class_test() { 52 | try { 53 | classSchemaBuilder.createClassInfo(InterfaceClass.class); 54 | Assert.fail(); 55 | } catch (RuntimeException e) {} 56 | } 57 | 58 | /** 59 | * 60 | */ 61 | private static interface InterfaceClass { 62 | 63 | } 64 | 65 | /** 66 | * 67 | */ 68 | private static abstract class AbstractClass { 69 | private int a; 70 | } 71 | 72 | /** 73 | * 74 | */ 75 | private static class ClassWithMergeableFields1 { 76 | private int a, b, c, d, e; 77 | private long f, g, h; 78 | private double i, j, k, l, m, n, o; 79 | private float p, q, r; 80 | private byte s, t, u; 81 | private short v, w; 82 | private boolean x, y, z; 83 | } 84 | 85 | /** 86 | * 87 | */ 88 | private static class ClassWithMergeableFields2 extends ClassWithMergeableFields1 { 89 | private int a, b, c, d, e; 90 | private long f, g, h; 91 | private double i, j, k, l, m, n, o; 92 | private float p, q, r; 93 | private byte s, t, u; 94 | private short v, w; 95 | private boolean x, y, z; 96 | } 97 | 98 | /** 99 | * 100 | */ 101 | private static class ClassWithMergeableFields3 extends ClassWithMergeableFields2 { 102 | private volatile int v1, v2; 103 | private String a; 104 | } 105 | 106 | 107 | /** 108 | * 109 | */ 110 | private static class TestSuperClass { 111 | private int a1; 112 | private Integer a2; 113 | } 114 | 115 | /** 116 | * 117 | */ 118 | private static class TestClass extends TestSuperClass { 119 | private String b; 120 | private double c1; 121 | private Double c2; 122 | private float d1; 123 | private Float d2; 124 | private short e1; 125 | private Short e2; 126 | } 127 | 128 | /** 129 | * 130 | */ 131 | private class ClassWithUnknownFieldTypes { 132 | private List collections; 133 | private volatile List volatileCollections; 134 | private int size; 135 | private String name; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /blixtser-core/src/test/java/com/mojang/blixtser/core/SuperClass.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | class SuperClass { 4 | 5 | protected int someInt; 6 | 7 | private transient volatile int a = 2; 8 | private final static float someFloat = 3.4f; 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /blixtser-core/src/test/java/com/mojang/blixtser/core/TestClasses.java: -------------------------------------------------------------------------------- 1 | package com.mojang.blixtser.core; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | import java.math.BigInteger; 8 | import java.util.Arrays; 9 | import java.util.Date; 10 | 11 | public class TestClasses { 12 | 13 | /** 14 | * Integers 15 | */ 16 | 17 | @Data 18 | @EqualsAndHashCode 19 | @AllArgsConstructor 20 | public static class IntPrimitiveTestClass { 21 | int a; 22 | volatile int b; 23 | } 24 | 25 | @Data 26 | @EqualsAndHashCode 27 | @AllArgsConstructor 28 | public static class IntNonPrimitiveTestClass { 29 | private Integer a; 30 | volatile Integer b; 31 | } 32 | 33 | @Data 34 | @EqualsAndHashCode 35 | @AllArgsConstructor 36 | public static class IntPrimitiveArrayTestClass { 37 | int[] a; 38 | volatile int[] b; 39 | } 40 | 41 | @Data 42 | @EqualsAndHashCode 43 | @AllArgsConstructor 44 | public static class IntPrimitive2DArrayTestClass { 45 | int[][] a; 46 | volatile int[][] b; 47 | } 48 | 49 | @Data 50 | @EqualsAndHashCode 51 | public static class BigIntegerTestClass { 52 | private BigInteger a; 53 | } 54 | 55 | /** 56 | * Longs 57 | */ 58 | 59 | @Data 60 | @EqualsAndHashCode 61 | @AllArgsConstructor 62 | public static class LongPrimitiveTestClass { 63 | long a; 64 | volatile long b; 65 | } 66 | 67 | @Data 68 | @EqualsAndHashCode 69 | @AllArgsConstructor 70 | public static class LongNonPrimitiveTestClass { 71 | Long a; 72 | volatile Long b; 73 | } 74 | 75 | @Data 76 | @EqualsAndHashCode 77 | @AllArgsConstructor 78 | public static class LongPrimitiveArrayTestClass { 79 | long[] a; 80 | volatile long[] b; 81 | } 82 | 83 | @Data 84 | @EqualsAndHashCode 85 | @AllArgsConstructor 86 | public static class LongPrimitive2DArrayTestClass { 87 | long[][] a; 88 | volatile long[][] b; 89 | } 90 | 91 | /** 92 | * Doubles 93 | */ 94 | 95 | @Data 96 | @EqualsAndHashCode 97 | @AllArgsConstructor 98 | public static class DoublePrimitiveTestClass { 99 | double a; 100 | volatile double b; 101 | } 102 | 103 | @Data 104 | @EqualsAndHashCode 105 | @AllArgsConstructor 106 | public static class DoubleNonPrimitiveTestClass { 107 | Double a; 108 | volatile Double b; 109 | } 110 | 111 | @Data 112 | @EqualsAndHashCode 113 | @AllArgsConstructor 114 | public static class DoublePrimitiveArrayTestClass { 115 | double[] a; 116 | volatile double[] b; 117 | } 118 | 119 | @Data 120 | @EqualsAndHashCode 121 | @AllArgsConstructor 122 | public static class DoublePrimitive2DArrayTestClass { 123 | double[][] a; 124 | volatile double[][] b; 125 | } 126 | 127 | /** 128 | * Floats 129 | */ 130 | 131 | @Data 132 | @EqualsAndHashCode 133 | @AllArgsConstructor 134 | public static class FloatPrimitiveTestClass { 135 | float a; 136 | volatile float b; 137 | } 138 | 139 | @Data 140 | @EqualsAndHashCode 141 | @AllArgsConstructor 142 | public static class FloatNonPrimitiveTestClass { 143 | Float a; 144 | volatile Float b; 145 | } 146 | 147 | @Data 148 | @EqualsAndHashCode 149 | @AllArgsConstructor 150 | public static class FloatPrimitiveArrayTestClass { 151 | float[] a; 152 | volatile float[] b; 153 | } 154 | 155 | @Data 156 | @EqualsAndHashCode 157 | @AllArgsConstructor 158 | public static class FloatPrimitive2DArrayTestClass { 159 | float[][] a; 160 | volatile float[][] b; 161 | } 162 | 163 | /** 164 | * Char 165 | */ 166 | 167 | @Data 168 | @EqualsAndHashCode 169 | @AllArgsConstructor 170 | public static class CharPrimitiveTestClass { 171 | char a; 172 | volatile char b; 173 | } 174 | 175 | @Data 176 | @EqualsAndHashCode 177 | @AllArgsConstructor 178 | public static class CharNonPrimitiveTestClass { 179 | Character a; 180 | volatile Character b; 181 | } 182 | 183 | @Data 184 | @EqualsAndHashCode 185 | @AllArgsConstructor 186 | public static class CharPrimitiveArrayTestClass { 187 | char[] a; 188 | volatile char[] b; 189 | } 190 | 191 | @Data 192 | @EqualsAndHashCode 193 | @AllArgsConstructor 194 | public static class CharPrimitive2DArrayTestClass { 195 | char[][] a; 196 | volatile char[][] b; 197 | } 198 | 199 | /** 200 | * Short 201 | */ 202 | 203 | @Data 204 | @EqualsAndHashCode 205 | @AllArgsConstructor 206 | public static class ShortPrimitiveTestClass { 207 | short a; 208 | volatile short b; 209 | } 210 | 211 | @Data 212 | @EqualsAndHashCode 213 | @AllArgsConstructor 214 | public static class ShortNonPrimitiveTestClass { 215 | Short a; 216 | volatile Short b; 217 | } 218 | 219 | @Data 220 | @EqualsAndHashCode 221 | @AllArgsConstructor 222 | public static class ShortPrimitiveArrayTestClass { 223 | short[] a; 224 | volatile short[] b; 225 | } 226 | 227 | @Data 228 | @EqualsAndHashCode 229 | @AllArgsConstructor 230 | public static class ShortPrimitive2DArrayTestClass { 231 | short[][] a; 232 | volatile short[][] b; 233 | } 234 | 235 | /** 236 | * Byte 237 | */ 238 | 239 | @Data 240 | @EqualsAndHashCode 241 | @AllArgsConstructor 242 | public static class BytePrimitiveTestClass { 243 | byte a; 244 | volatile byte b; 245 | } 246 | 247 | @Data 248 | @EqualsAndHashCode 249 | @AllArgsConstructor 250 | public static class ByteNonPrimitiveTestClass { 251 | Byte a; 252 | volatile Byte b; 253 | } 254 | 255 | @Data 256 | @EqualsAndHashCode 257 | @AllArgsConstructor 258 | public static class BytePrimitiveArrayTestClass { 259 | byte[] a; 260 | volatile byte[] b; 261 | } 262 | 263 | @Data 264 | @EqualsAndHashCode 265 | @AllArgsConstructor 266 | public static class BytePrimitive2DArrayTestClass { 267 | byte[][] a; 268 | volatile byte[][] b; 269 | } 270 | 271 | /** 272 | * Boolean 273 | */ 274 | 275 | @Data 276 | @EqualsAndHashCode 277 | @AllArgsConstructor 278 | public static class BooleanPrimitiveTestClass { 279 | boolean a; 280 | volatile boolean b; 281 | } 282 | 283 | @Data 284 | @EqualsAndHashCode 285 | @AllArgsConstructor 286 | public static class BooleanNonPrimitiveTestClass { 287 | Boolean a; 288 | volatile Boolean b; 289 | } 290 | 291 | @Data 292 | @EqualsAndHashCode 293 | @AllArgsConstructor 294 | public static class BooleanPrimitiveArrayTestClass { 295 | boolean[] a; 296 | volatile boolean[] b; 297 | } 298 | 299 | @Data 300 | @EqualsAndHashCode 301 | @AllArgsConstructor 302 | public static class BooleanPrimitive2DArrayTestClass { 303 | boolean[][] a; 304 | volatile boolean[][] b; 305 | } 306 | 307 | /** 308 | * String 309 | */ 310 | 311 | @Data 312 | @EqualsAndHashCode 313 | @AllArgsConstructor 314 | public static class StringTestClass { 315 | String a; 316 | volatile String b; 317 | } 318 | 319 | @Data 320 | @AllArgsConstructor 321 | public static class StringBuilderTestClass { 322 | StringBuilder a; 323 | volatile StringBuilder b; 324 | 325 | @Override 326 | public boolean equals(Object o) { 327 | if (this == o) return true; 328 | if (!(o instanceof StringBuilderTestClass)) return false; 329 | 330 | StringBuilderTestClass that = (StringBuilderTestClass) o; 331 | 332 | return !(a != null && that.a != null) || a.toString().equals(that.a.toString()); 333 | 334 | } 335 | 336 | @Override 337 | public int hashCode() { 338 | return a != null ? a.hashCode() : 0; 339 | } 340 | } 341 | 342 | @Data 343 | @AllArgsConstructor 344 | public static class StringBufferTestClass { 345 | StringBuffer a; 346 | volatile StringBuffer b; 347 | 348 | @Override 349 | public boolean equals(Object o) { 350 | if (this == o) return true; 351 | if (!(o instanceof StringBufferTestClass)) return false; 352 | 353 | StringBufferTestClass that = (StringBufferTestClass) o; 354 | 355 | return !(a != null && that.a != null) || a.toString().equals(that.a.toString()); 356 | 357 | } 358 | 359 | @Override 360 | public int hashCode() { 361 | return a != null ? a.hashCode() : 0; 362 | } 363 | 364 | } 365 | 366 | @Data 367 | @EqualsAndHashCode 368 | @AllArgsConstructor 369 | public static class StringArrayTestClass { 370 | String[] a; 371 | volatile String[] b; 372 | } 373 | 374 | @Data 375 | @EqualsAndHashCode 376 | @AllArgsConstructor 377 | public static class String2DArrayTestClass { 378 | String[][] a; 379 | volatile String[][] b; 380 | } 381 | 382 | /** 383 | * Enums 384 | */ 385 | 386 | @Data 387 | @EqualsAndHashCode 388 | @AllArgsConstructor 389 | public static class EnumTestClass { 390 | SomeEnum a; 391 | volatile SomeEnum b; 392 | 393 | public enum SomeEnum { 394 | A, 395 | B, 396 | C 397 | } 398 | } 399 | 400 | /** 401 | * 402 | */ 403 | public static class NullClass { 404 | 405 | String aString; 406 | StringBuffer aStringBuffer; 407 | String[] aStringArray = new String[10]; 408 | 409 | @Override 410 | public boolean equals(Object o) { 411 | if (this == o) return true; 412 | if (!(o instanceof NullClass)) return false; 413 | 414 | NullClass nullClass = (NullClass) o; 415 | 416 | if (aString == null && nullClass.aString == null) 417 | return true; 418 | 419 | if (aStringBuffer == null && nullClass.aStringBuffer == null) 420 | return true; 421 | 422 | if (aStringArray == null && nullClass.aStringArray == null) 423 | return true; 424 | 425 | if (aString != null ? !aString.equals(nullClass.aString) : nullClass.aString != null) return false; 426 | 427 | if (aStringBuffer != null ? !aStringBuffer.toString().equals(nullClass.aStringBuffer.toString()) : nullClass.aStringBuffer != null) return false; 428 | 429 | if (aStringArray.length != nullClass.aStringArray.length) return false; 430 | 431 | for (int i=0; i