All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nustaq.offheap.bytez.onheap.HeapBytez Maven / Gradle / Ivy

Go to download

A fast java serialization drop in-replacement and some serialization based utils such as Structs and OffHeap Memory.

There is a newer version: 3.0.4-jdk17
Show newest version
/*
 * 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.bytez.onheap;

import org.nustaq.offheap.bytez.BasicBytez;
import org.nustaq.offheap.bytez.Bytez;
import org.nustaq.offheap.bytez.malloc.MallocBytez;
import org.nustaq.serialization.util.FSTUtil;
import sun.misc.Unsafe;

import java.util.Arrays;

/**
 * Date: 16.11.13
 * Time: 12:41
 * To change this template use File | Settings | File Templates.
 */

/**
 * byte array abstraction based on heap byte arrays. FIXME: Should be moved to ordinary safe access as it really seems not to make
 * a big difference.
 */
public class HeapBytez implements Bytez {
    static Unsafe unsafe = FSTUtil.getUnsafe();
    static long byteoff = FSTUtil.bufoff;
    static long caoff = FSTUtil.choff;
    static long saoff = FSTUtil.choff;
    static long iaoff = FSTUtil.intoff;
    static long laoff = FSTUtil.longoff;
    static long daoff = FSTUtil.doubleoff;
    static long faoff = FSTUtil.floatoff;

    byte[] base;
    long off;
    long len;

    private void checkIndex(long index, int len ) {
//        if ( index >= base.length || index < off-byteoff ) {
//            throw new RuntimeException("aua");
//        }
//        index += len-1;
//        if ( index >= base.length || index < off-byteoff ) {
//            throw new RuntimeException("aua 1");
//        }
    }

    public HeapBytez(byte[] base) {
        this(base,0);
    }

    public HeapBytez(int size) {
        this(new byte[size],0);
    }
    public HeapBytez(byte[] base, long offIndex) {
        this(base,offIndex, base.length-offIndex);
    }

    public HeapBytez(byte[] base, long offIndex, long len) {
        setBase(base, offIndex, len);
    }

    public void setBase(byte[] base, long offIndex, long len) {
        this.base = base;
        this.off = byteoff+offIndex;
        this.len = len;
    }

    public HeapBytez slice(long off, int len) {
        if (off+len >= base.length)
            throw new RuntimeException("invalid slice "+off+":"+len+" mylen:"+base.length);
        return new HeapBytez(base,off,len);
    }

    @Override
    public byte get(long byteIndex) {
        checkIndex(byteIndex,1);
        return unsafe.getByte(base,off+byteIndex);
    }

    @Override
    public boolean getBool(long byteIndex) {
        checkIndex(byteIndex,1);
        return unsafe.getByte(base,off+byteIndex) != 0;
    }

    @Override
    public char getChar(long byteIndex) {
        checkIndex(byteIndex,2);
        return unsafe.getChar(base, off + byteIndex);
    }

    @Override
    public short getShort(long byteIndex) {
        checkIndex(byteIndex,2);
        return unsafe.getShort(base, off + byteIndex);
    }

    @Override
    public int getInt(long byteIndex) {
        checkIndex(byteIndex,4);
        int res = unsafe.getInt(base, off + byteIndex);
        return res;
    }

    @Override
    public long getLong(long byteIndex) {
        checkIndex(byteIndex,8);
        return unsafe.getLong(base, off + byteIndex);
    }

    @Override
    public float getFloat(long byteIndex) {
        checkIndex(byteIndex,4);
        return unsafe.getFloat(base, off + byteIndex);
    }

    @Override
    public double getDouble(long byteIndex) {
        checkIndex(byteIndex,8);
        return unsafe.getDouble(base, off + byteIndex);
    }

    @Override
    public void put(long byteIndex, byte value) {
        checkIndex(byteIndex,1);
        unsafe.putByte(base,off+byteIndex,value);
    }

    @Override
    public void putBool(long byteIndex, boolean val) {
        checkIndex(byteIndex,1);
        put(byteIndex,(byte) (val ? 1 : 0) );
    }

    @Override
    public void putChar(long byteIndex, char c) {
        checkIndex(byteIndex,2);
        unsafe.putChar(base, off + byteIndex, c);
    }

    @Override
    public void putShort(long byteIndex, short s) {
        checkIndex(byteIndex,2);
        unsafe.putShort(base, off + byteIndex, s);
    }

    @Override
    public void putInt(long byteIndex, int i) {
        checkIndex(byteIndex,4);
        unsafe.putInt(base, off + byteIndex, i);
    }

    @Override
    public void putLong(long byteIndex, long l) {
        checkIndex(byteIndex,8);
        unsafe.putLong(base, off + byteIndex, l);
    }

    @Override
    public void putFloat(long byteIndex, float f) {
        checkIndex(byteIndex,4);
        unsafe.putFloat(base, off + byteIndex, f);
    }

    @Override
    public void putDouble(long byteIndex, double d) {
        checkIndex(byteIndex,8);
        unsafe.putDouble(base, off + byteIndex, d);
    }

    @Override
    public long length() {
        return len;
    }

    @Override
    public void getArr(long byteIndex, byte[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,off+elemoff,numElems);
    }

    @Override
    public void getCharArr(long byteIndex, char[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,caoff+elemoff*2+off-byteoff,numElems*2);
    }

    @Override
    public void getShortArr(long byteIndex, short[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,saoff+elemoff*2+off-byteoff,numElems*2);
    }

    @Override
    public void getIntArr(long byteIndex, int[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,iaoff+elemoff*4+off-byteoff,numElems*4);
    }

    @Override
    public void getLongArr(long byteIndex, long[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,laoff+elemoff*8+off-byteoff,numElems*8);
    }

    @Override
    public void getFloatArr(long byteIndex, float[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,faoff+elemoff*4+off-byteoff,numElems*4);
    }

    @Override
    public void getDoubleArr(long byteIndex, double[] target, int elemoff, int numElems) {
        unsafe.copyMemory(base,off+byteIndex,target,daoff+elemoff*4+off-byteoff,numElems*8);
    }

    @Override
    public void getBooleanArr(long byteIndex, boolean[] target, int elemoff, int numElems) {
        for ( int i = 0; i < numElems; i++) {
            target[elemoff+i] = getBool(byteIndex+i);
        }
    }

    @Override
    public void set(long byteIndex, byte[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems);
        unsafe.copyMemory(source,off+elemoff,base,off+byteIndex,numElems);
    }

    @Override
    public void setChar(long byteIndex, char[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems*2);
        unsafe.copyMemory(source,caoff+off-byteoff+elemoff*2,base,off+byteIndex,numElems*2);
    }

    @Override
    public void setShort(long byteIndex, short[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems*2);
        unsafe.copyMemory(source,caoff+off-byteoff+elemoff*2,base,off+byteIndex,numElems*2);
    }

    @Override
    public void setInt(long byteIndex, int[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems*4);
        unsafe.copyMemory(source,iaoff+off-byteoff+elemoff*4,base,off+byteIndex,numElems*4);
    }

    @Override
    public void setLong(long byteIndex, long[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems*8);
        unsafe.copyMemory(source,laoff+off-byteoff+elemoff*8,base,off+byteIndex,numElems*8);
    }

    @Override
    public void setFloat(long byteIndex, float[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems*4);
        unsafe.copyMemory(source,faoff+off-byteoff+elemoff*4,base,off+byteIndex,numElems*4);
    }

    @Override
    public void setDouble(long byteIndex, double[] source, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems*8);
        unsafe.copyMemory(source,daoff+off-byteoff+elemoff*8,base,off+byteIndex,numElems*8);
    }

    @Override
    public void setBoolean(long byteIndex, boolean[] o, int elemoff, int numElems) {
        checkIndex(byteIndex,numElems);
        for ( int i = 0; i < numElems; i++) {
            put(byteIndex+i, (byte) (o[i+elemoff] ? 1 : 0));
        }
    }

    @Override
    public void copyTo(BasicBytez other, long otherByteIndex, long myByteIndex, long lenBytes) {
        if ( lenBytes == 0 )
            return;
        checkIndex(myByteIndex, (int) lenBytes);
        if ( other instanceof HeapBytez) {
            HeapBytez hp = (HeapBytez) other;
            unsafe.copyMemory(base,off+myByteIndex,hp.base,hp.off+otherByteIndex,lenBytes);
        } else if (other instanceof MallocBytez ) {
            MallocBytez mb = (MallocBytez) other;
            unsafe.copyMemory(base,off+myByteIndex,null,otherByteIndex+mb.getBaseAdress(),lenBytes);
        } else {
            for ( long i = 0; i < lenBytes; i++ ) {
                other.put(otherByteIndex+i,get(myByteIndex+i));
            }
        }
    }

    @Override
    public BasicBytez newInstance(long size) {
        return new HeapBytez(new byte[(int) size]);
    }

    @Override
    public boolean compareAndSwapInt(long offset, int expect, int newVal) {
        return unsafe.compareAndSwapInt(base,off+offset,expect,newVal);
    }

    @Override
    public boolean compareAndSwapLong(long offset, long expect, long newVal) {
        return unsafe.compareAndSwapLong(base, off + offset, expect, newVal);
    }

    @Override
    public byte[] toBytes(long startIndex, int len) {
        byte res[] = new byte[len];
        System.arraycopy(base, (int) (off-FSTUtil.bufoff)+(int)startIndex,res,0,len);
        return res;
    }

    @Override
    public byte[] asByteArray() {
        return base;
    }

    /**
     * @return the start index inside the byte array returned by asByteArray, not supported by MallocBytez
     */
    @Override
    public int getBAOffsetIndex() {
        return (int) (off- FSTUtil.bufoff);
    }

    /**
     * @return the length inside the byte array returned by asByteArray, not supported by MallocBytez
     */
    @Override
    public int getBALength() {
        return 0;  //To change body of implemented methods use File | Settings | File Templates.
    }

    int hash;
    @Override
    public int hashCode() {
        int h = hash;
        if (h == 0 && length() > 0) {
            for (int i = 0; i < length(); i++) {
                h = 31 * h + get(i);
            }
            hash = h;
        }
        return h;
    }

    @Override
    public boolean equals(Object obj) {
        if ( obj instanceof HeapBytez) {
            HeapBytez other = (HeapBytez) obj;
            if ( other.length() != length() )
                return false;
            for ( int i=0; i < length(); i++ ) {
                if ( get(i) != other.get(i) ) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean getBoolVolatile(long byteIndex) {
        return getVolatile(byteIndex) != 0;
    }

    @Override
    public byte getVolatile(long byteIndex) {
        return unsafe.getByteVolatile(base, off + byteIndex);
    }

    @Override
    public char getCharVolatile(long byteIndex) {
        return unsafe.getCharVolatile(base, off + byteIndex);
    }

    @Override
    public short getShortVolatile(long byteIndex) {
        return unsafe.getShortVolatile(base, off + byteIndex);
    }

    @Override
    public int getIntVolatile(long byteIndex) {
        return unsafe.getIntVolatile(base, off + byteIndex);
    }

    @Override
    public long getLongVolatile(long byteIndex) {
        return unsafe.getLongVolatile(base, off + byteIndex);
    }

    @Override
    public float getFloatVolatile(long byteIndex) {
        return unsafe.getFloatVolatile(base, off + byteIndex);
    }

    @Override
    public double getDoubleVolatile(long byteIndex) {
        return unsafe.getDoubleVolatile(base, off + byteIndex);
    }

    @Override
    public void putBoolVolatile(long byteIndex, boolean value) {
        putVolatile(byteIndex, (byte) (value?1:0));
    }

    @Override
    public void putVolatile(long byteIndex, byte value) {
        unsafe.putByteVolatile(base, off + byteIndex, value);
    }

    @Override
    public void putCharVolatile(long byteIndex, char c) {
        unsafe.putCharVolatile(base, off + byteIndex, c);
    }

    @Override
    public void putShortVolatile(long byteIndex, short s) {
        unsafe.putShortVolatile(base, off + byteIndex, s);
    }

    @Override
    public void putIntVolatile(long byteIndex, int i) {
        unsafe.putIntVolatile(base, off + byteIndex, i);
    }

    @Override
    public void putLongVolatile(long byteIndex, long l) {
        unsafe.putLongVolatile(base, off + byteIndex, l);
    }

    @Override
    public void putFloatVolatile(long byteIndex, float f) {
        unsafe.putFloatVolatile(base, off + byteIndex, f);
    }

    @Override
    public void putDoubleVolatile(long byteIndex, double d) {
        unsafe.putDoubleVolatile(base, off + byteIndex, d);
    }


    public byte[] getBase() {
        return base;
    }

    /**
     * @return offset to byte array INCLUDING native bytearray header
     */
    public long getOff() {
        return off;
    }

    /**
     * @return offset to byte array EXCLUDING native bytearray header
     */
    public long getOffsetIndex() {
        return off-byteoff;
    }

    @Override
    public String toString() {
        return "HeapBytez{" +
                "base=" + base +
                ", off=" + off +
                ", len=" + len +
                '}';
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy