org.nustaq.offheap.structs.FSTStructAllocator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fst Show documentation
Show all versions of fst Show documentation
A fast java serialization drop in-replacement and some serialization based utils such as Structs and OffHeap Memory.
/*
* Copyright 2014 Ruediger Moeller.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nustaq.offheap.structs;
import org.nustaq.offheap.bytez.Bytez;
import org.nustaq.offheap.bytez.BytezAllocator;
import org.nustaq.offheap.bytez.malloc.MallocBytezAllocator;
import org.nustaq.offheap.bytez.onheap.HeapBytezAllocator;
import org.nustaq.offheap.structs.structtypes.StructArray;
import org.nustaq.offheap.structs.unsafeimpl.FSTStructFactory;
import org.nustaq.serialization.util.FSTUtil;
/**
* Date: 04.10.13
* Time: 20:51
* implemenst struct instances. By default heap is used to obtain underlying byte arrays.
* By supplementing a BytezAllocator, structs can also be created offheap.
*/
public class FSTStructAllocator {
public static boolean DUMP_ALLOC = false;
protected int chunkSize;
protected Bytez chunk;
protected int chunkIndex;
BytezAllocator alloc = new HeapBytezAllocator();
int chunkObjCount = 0;
// BytezAllocator alloc = new MallocBytezAllocator();
protected FSTStructAllocator() {
}
/**
* @param b
* @param index
* @return a new allocated pointer matching struct type stored in b[]
*/
public static FSTStruct createStructPointer(Bytez b, int index) {
return FSTStructFactory.getInstance().getStructPointerByOffset(b, index).detach();
}
/**
* @param onHeapTemplate
* @param
* @return return a byte array based struct instance for given on-heap template. Allocates a new byte[] with each call
*/
public static T toStruct(T onHeapTemplate) {
return FSTStructFactory.getInstance().toStruct(onHeapTemplate);
}
/**
* @param b
* @param index
* @return a pointer matching struct type stored in b[] from the thread local cache
*/
public static FSTStruct getVolatileStructPointer(Bytez b, int index) {
return (FSTStruct) FSTStructFactory.getInstance().getStructPointerByOffset(b, index);
}
/**
* @param clazz
* @param
* @return a newly allocated pointer matching. use baseOn to point it to a meaningful location
*/
public static C newPointer(Class clazz) {
try {
return (C) allocInstance(clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected static Object allocInstance(Class clazz) throws Exception {
return FSTUtil.getUnsafe().allocateInstance(FSTStructFactory.getInstance().getProxyClass(clazz));
// return FSTStructFactory.getInstance().getProxyClass(clazz).newInstance();
}
/**
* Create a Heap-Byte Array Structallocator with given chunk size in bytes. If allocated structs are larger than the given size, a new bytearray is
* created for the allocation.
* @param chunkSizeBytes
*/
public FSTStructAllocator(int chunkSizeBytes) {
this.chunkSize = chunkSizeBytes;
}
/**
* optionally uses another allocator (e.g. for Real Off Heap with MallocBytez)
*
* Warning: Currently there is not automatic free for OffHeap Bytez, so only use for
* statically allocated structures. You can call free() to release all offheap structures
* allocated by this instance, however you'll get crashes if there are still references
* from y StructArray newArray(int size, X templ) {
return newArray(size,templ,alloc);
}
/**
* create a new struct array of same type as template
* @param size
* @return
*/
public StructArray newArray(int size, X templ, BytezAllocator alloc) {
StructArray aTemplate = new StructArray(size, templ);
int siz = getFactory().calcStructSize(aTemplate);
try {
if ( siz < chunkSize )
return newStruct(aTemplate);
else {
return getFactory().toStruct(aTemplate,alloc);
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
/**
* frees associated offheap memory, in case making objects created INVALID (Access violation!).
* is a noop for on heap byte array allocator
*/
public void free() {
alloc.freeAll();
}
/**
* allocate a Struct instance from an arbitrary template instance.
*
* @param aTemplate
* @param
* @return
*/
public S newStruct(S aTemplate) {
return newStruct(aTemplate,alloc);
}
public S newStruct(S aTemplate, BytezAllocator alloc) {
aTemplate = getFactory().toStruct(aTemplate);
if (aTemplate.getByteSize()>=chunkSize)
return (S)aTemplate.createCopy();
int byteSize = aTemplate.getByteSize();
synchronized (this) {
if (chunk == null || chunkIndex+byteSize >= chunk.length()) {
chunk = alloc.alloc(chunkSize);
if ( DUMP_ALLOC )
System.out.println("[Allocator] sum allocated "+MallocBytezAllocator.alloced.get()/1024/1024+" MB");
chunkIndex = 0;
chunkObjCount = 0;
}
// FSTStruct.unsafe.copyMemory(aTemplate.___bytes, aTemplate.___offset, chunk, FSTStruct.bufoff + chunkIndex, byteSize);
aTemplate.___bytes.copyTo(chunk, chunkIndex, aTemplate.___offset, byteSize);
S res = (S) getFactory().createStructWrapper(chunk, chunkIndex );
chunkIndex+=byteSize;
chunkObjCount++;
return res;
}
}
protected FSTStructFactory getFactory() {
return FSTStructFactory.getInstance();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy