package org.kne.cloud.network; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySegment.Scope; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReentrantLock; public class DirectBufferedArena implements Arena{ private static long blockSize=1024*1024L; private volatile PreAlloc buffer; public static long getBlockSize() { return blockSize; } public static void setBlockSize(long blockSizex) { blockSize = blockSizex; } private class PreAlloc{ private MemorySegment segment; private AtomicLong pos=new AtomicLong(0); private AtomicLong refs=new AtomicLong(0); public MemorySegment getSegment() { return segment; } public AtomicLong getPos() { return pos; } public PreAlloc(MemorySegment segment) { super(); this.segment = segment; } public long byteSize() { return segment.byteSize(); } public AtomicLong getRefs() { return refs; } } private void allocateNew(long blockSize2) { MemorySegment raw=MemorySegment.ofArray(ByteBufferAllocator.allocateUninitializedArray((int) blockSize2)); buffer=new PreAlloc(raw); } public DirectBufferedArena() { super(); allocateNew(blockSize); } @Override public MemorySegment allocate(long byteSize, long byteAlignment) { if(byteSize>blockSize) throw new IndexOutOfBoundsException("byteSize can't large than buffer block"); long pos; PreAlloc bufferx; do{ bufferx=this.buffer; pos=bufferx.getPos().getAndAdd(byteSize); if(pos+byteSize>bufferx.byteSize()) { allocateNew(blockSize); }else { break; } }while(true); bufferx.getRefs().incrementAndGet(); MemorySegment sliced=bufferx.getSegment().asSlice(pos, byteSize); return sliced; } @Override public Scope scope() { return null; } @Override public void close() { } public static DirectBufferedArena ofBuffered() { return new DirectBufferedArena(); } }