完善 ByteArray 的写出

master
linbin 2024-04-12 18:08:55 +08:00
parent 1714fbd246
commit 323f003df2
5 changed files with 865 additions and 497 deletions

View File

@ -1,11 +1,67 @@
package com.jfirer.se;
import io.github.karlatemp.unsafeaccessor.Unsafe;
import java.lang.reflect.Field;
import java.nio.ByteOrder;
public class ByteArray
{
protected byte[] array;
protected int writePosi = 0;
protected int readIndex = 0;
protected boolean needCheck = true;
protected static final boolean LITTLE_ENDIAN = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
protected static final Unsafe UNSAFE = Unsafe.getUnsafe();
public static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
public static final int BOOLEAN_ARRAY_OFFSET;
public static final int BYTE_ARRAY_OFFSET;
public static final int CHAR_ARRAY_OFFSET;
public static final int SHORT_ARRAY_OFFSET;
public static final int INT_ARRAY_OFFSET;
public static final int LONG_ARRAY_OFFSET;
public static final int FLOAT_ARRAY_OFFSET;
public static final int DOUBLE_ARRAY_OFFSET;
public static final boolean STRING_VALUE_FIELD_IS_CHARS;
public static final boolean STRING_VALUE_FIELD_IS_BYTES;
public static final long STRING_VALUE_FIELD_OFFSET;
public static final long STRING_CODER_FIELD_OFFSET;
protected byte[] array;
protected int writerIndex = 0;
protected int readerIndex = 0;
protected boolean needCheck = true;
static
{
BOOLEAN_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(boolean[].class);
BYTE_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
CHAR_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(char[].class);
SHORT_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(short[].class);
INT_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(int[].class);
LONG_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(long[].class);
FLOAT_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(float[].class);
DOUBLE_ARRAY_OFFSET = UNSAFE.arrayBaseOffset(double[].class);
try
{
Field field = String.class.getDeclaredField("value");
STRING_VALUE_FIELD_OFFSET = UNSAFE.objectFieldOffset(field);
// Java8 string
STRING_VALUE_FIELD_IS_CHARS = field != null && field.getType() == char[].class;
// Java11 string
STRING_VALUE_FIELD_IS_BYTES = field != null && field.getType() == byte[].class;
}
catch (NoSuchFieldException e)
{
throw new RuntimeException(e);
}
long stringCoderFieldOffset1;
try
{
Field field = String.class.getDeclaredField("coder");
stringCoderFieldOffset1 = UNSAFE.objectFieldOffset(field);
}
catch (NoSuchFieldException e)
{
stringCoderFieldOffset1 = 0;
}
STRING_CODER_FIELD_OFFSET = stringCoderFieldOffset1;
}
protected ByteArray(int size)
{
@ -14,7 +70,8 @@ public class ByteArray
protected ByteArray(byte[] array)
{
this.array = array;
this.array = array;
writerIndex = array.length;
}
public static ByteArray allocate(int size)
@ -37,11 +94,11 @@ public class ByteArray
this.needCheck = needCheck;
}
protected void ensureCapacity(int len)
protected void ensureNewWriterIndex(int newWriterIndex)
{
if (needCheck && len > array.length - writePosi)
if (newWriterIndex > array.length)
{
int newLen = len + writePosi > (array.length << 1) ? len + writePosi + array.length : (array.length << 1);
int newLen = newWriterIndex > (array.length << 1) ? newWriterIndex : (array.length << 1);
byte[] tmp = new byte[newLen];
System.arraycopy(array, 0, tmp, 0, array.length);
array = tmp;
@ -50,54 +107,55 @@ public class ByteArray
public void clear()
{
writePosi = readIndex = 0;
writerIndex = readerIndex = 0;
}
public void put(byte value)
{
ensureCapacity(1);
array[writePosi] = value;
writePosi += 1;
}
public void setByte(int off, byte b)
{
array[off] = b;
}
public void put(byte[] data)
{
ensureCapacity(data.length);
System.arraycopy(data, 0, array, writePosi, data.length);
writePosi += data.length;
int writerIdx = writerIndex;
int newWriterIndex = writerIdx + 1;
ensureNewWriterIndex(newWriterIndex);
UNSAFE.putByte(array, BYTE_ARRAY_OFFSET + writerIdx, value);
writerIndex = newWriterIndex;
}
public byte get()
{
byte result = array[readIndex];
readIndex += 1;
return result;
int readerIdx = readerIndex;
if (readerIdx < writerIndex)
{
byte result = UNSAFE.getByte(array, BYTE_ARRAY_OFFSET + readerIdx);
readerIndex = readerIdx + 1;
return result;
}
else
{
throw new IllegalArgumentException("读取的内容不足");
}
// byte result = array[readIndex];
// readIndex += 1;
// return result;
}
public byte[] toArray()
{
byte[] result = new byte[writePosi];
System.arraycopy(array, 0, result, 0, writePosi);
byte[] result = new byte[writerIndex];
System.arraycopy(array, 0, result, 0, writerIndex);
return result;
}
public int getWritePosi()
public int getWriterIndex()
{
return writePosi;
return writerIndex;
}
public void setWritePosi(int writePosi)
public void setWriterIndex(int writerIndex)
{
this.writePosi = writePosi;
this.writerIndex = writerIndex;
}
public void setReadPosi(int readPosi)
{
this.readIndex = readPosi;
this.readerIndex = readPosi;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@ public class JfireSE
classInfoResolver.reset();
}
byte[] result = byteArray.toArray();
byteArray.setWritePosi(0);
byteArray.setWriterIndex(0);
return result;
}

View File

@ -21,20 +21,15 @@ import java.util.concurrent.TimeUnit;
@State(Scope.Benchmark)
public class BenchMark
{
Fse fse = new Fse();
Fse fse_3 = new Fse().useCompile();
TestData data = new TestData();
ByteArray buf = ByteArray.allocate(100);
Fury fury = Fury.builder().withLanguage(Language.JAVA)//
Fse fse = new Fse();
Fse fse_3 = new Fse().useCompile();
TestData data = new TestData();
ByteArray buf = ByteArray.allocate(100);
Fury fury = Fury.builder().withLanguage(Language.JAVA)//
.requireClassRegistration(false)//
.withRefTracking(true).build();
JfireSE jfireSE = new JfireSE();
@Setup
public void before(){
jfireSE.registerClass(TestData.class);
}
@Benchmark
public void testNoCompile()
{

View File

@ -1,6 +1,9 @@
package org.example;
import com.jfirer.se.ByteArray;
import com.jfirer.se.InternalByteArray;
import com.jfirer.se.JfireSE;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
@ -22,9 +25,12 @@ public class FunctionTest
@Test
public void test2()
{
TestData data = new TestData();
JfireSE jfireSE = new JfireSE();
byte[] bytes = jfireSE.writeBytes(data);
Object o = jfireSE.readBytes(bytes);
InternalByteArray byteArray = (InternalByteArray) ByteArray.allocate();
byteArray.writeVarInt(5);
Assert.assertEquals(5, byteArray.readVarInt());
byteArray.writeVarInt(200);
Assert.assertEquals(200, byteArray.readVarInt());
byteArray.writeVarInt(7000);
Assert.assertEquals(7000, byteArray.readVarInt());
}
}