Package com.esotericsoftware.kryo.serializers

Source Code of com.esotericsoftware.kryo.serializers.UnsafeCacheFields$UnsafeStringField

package com.esotericsoftware.kryo.serializers;

import static com.esotericsoftware.kryo.util.UnsafeUtil.unsafe;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.io.UnsafeInput;
import com.esotericsoftware.kryo.io.UnsafeMemoryInput;
import com.esotericsoftware.kryo.io.UnsafeMemoryOutput;
import com.esotericsoftware.kryo.io.UnsafeOutput;
import com.esotericsoftware.kryo.serializers.FieldSerializer.CachedField;
import com.esotericsoftware.reflectasm.FieldAccess;

/*** Implementations of java.misc.Unsafe-based serializers for fields.
*
* @author Roman Levenstein <romixlev@gmail.com> */
public class UnsafeCacheFields {

  abstract static class UnsafeCachedField extends CachedField {
    UnsafeCachedField (long offset) {
      this.offset = offset;
    }
  }

  final static class UnsafeIntField extends UnsafeCachedField {
    public UnsafeIntField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      if (varIntsEnabled)
        output.writeInt(unsafe().getInt(object, offset), false);
      else
        output.writeInt(unsafe().getInt(object, offset));
    }

    public void read (Input input, Object object) {
      if (varIntsEnabled)
        unsafe().putInt(object, offset, input.readInt(false));
      else
        unsafe().putInt(object, offset, input.readInt());
    }

    public void copy (Object original, Object copy) {
      unsafe().putInt(copy, offset, unsafe().getInt(original, offset));
    }
  }

  final static class UnsafeFloatField extends UnsafeCachedField {
    public UnsafeFloatField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeFloat(unsafe().getFloat(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putFloat(object, offset, input.readFloat());
    }

    public void copy (Object original, Object copy) {
      unsafe().putFloat(copy, offset, unsafe().getFloat(original, offset));
    }
  }

  final static class UnsafeShortField extends UnsafeCachedField {
    public UnsafeShortField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeShort(unsafe().getShort(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putShort(object, offset, input.readShort());
    }

    public void copy (Object original, Object copy) {
      unsafe().putShort(copy, offset, unsafe().getShort(original, offset));
    }
  }

  final static class UnsafeByteField extends UnsafeCachedField {
    public UnsafeByteField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeByte(unsafe().getByte(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putByte(object, offset, input.readByte());
    }

    public void copy (Object original, Object copy) {
      unsafe().putByte(copy, offset, unsafe().getByte(original, offset));
    }
  }

  final static class UnsafeBooleanField extends UnsafeCachedField {
    public UnsafeBooleanField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeBoolean(unsafe().getBoolean(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putBoolean(object, offset, input.readBoolean());
    }

    public void copy (Object original, Object copy) {
      unsafe().putBoolean(copy, offset, unsafe().getBoolean(original, offset));
    }
  }

  final static class UnsafeCharField extends UnsafeCachedField {
    public UnsafeCharField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeChar(unsafe().getChar(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putChar(object, offset, input.readChar());
    }

    public void copy (Object original, Object copy) {
      unsafe().putChar(copy, offset, unsafe().getChar(original, offset));
    }
  }

  final static class UnsafeLongField extends UnsafeCachedField {
    public UnsafeLongField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      if (varIntsEnabled)
        output.writeLong(unsafe().getLong(object, offset), false);
      else
        output.writeLong(unsafe().getLong(object, offset));
    }

    public void read (Input input, Object object) {
      if (varIntsEnabled)
        unsafe().putLong(object, offset, input.readLong(false));
      else
        unsafe().putLong(object, offset, input.readLong());
    }

    public void copy (Object original, Object copy) {
      unsafe().putLong(copy, offset, unsafe().getLong(original, offset));
    }
  }

  final static class UnsafeDoubleField extends UnsafeCachedField {
    public UnsafeDoubleField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeDouble(unsafe().getDouble(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putDouble(object, offset, input.readDouble());
    }

    public void copy (Object original, Object copy) {
      unsafe().putDouble(copy, offset, unsafe().getDouble(original, offset));
    }
  }

  final static class UnsafeStringField extends UnsafeCachedField {
    public UnsafeStringField (Field f) {
      super(unsafe().objectFieldOffset(f));
    }

    public void write (Output output, Object object) {
      output.writeString((String)unsafe().getObject(object, offset));
    }

    public void read (Input input, Object object) {
      unsafe().putObject(object, offset, input.readString());
    }

    public void copy (Object original, Object copy) {
      unsafe().putObject(copy, offset, unsafe().getObject(original, offset));
    }
  }

  /** Helper class for doing bulk copies of memory regions containing adjacent primitive fields. Should be normally used only with
   * Unsafe streams to deliver best performance. */
  final static class UnsafeRegionField extends UnsafeCachedField {
    final long len;
    static final boolean bulkReadsSupported = false;

    public UnsafeRegionField (long offset, long len) {
      super(offset);
      this.len = len;
    }

    final public void write (Output output, Object object) {
      if (output instanceof UnsafeOutput) {
        UnsafeOutput unsafeOutput = (UnsafeOutput)output;
        unsafeOutput.writeBytes(object, offset, len);
      } else if (output instanceof UnsafeMemoryOutput) {
        UnsafeMemoryOutput unsafeOutput = (UnsafeMemoryOutput)output;
        unsafeOutput.writeBytes(object, offset, len);
      } else {
        long off;
        Unsafe unsafe = unsafe();
        for (off = offset; off < offset + len - 8; off += 8) {
          output.writeLong(unsafe.getLong(object, off));
        }

        if (off < offset + len) {
          for (; off < offset + len; ++off) {
            output.write(unsafe.getByte(object, off));
          }
        }
      }
    }

    final public void read (Input input, Object object) {
      if (bulkReadsSupported && input instanceof UnsafeInput) {
        UnsafeInput unsafeInput = (UnsafeInput)input;
        unsafeInput.readBytes(object, offset, len);
      } else if (bulkReadsSupported && input instanceof UnsafeMemoryInput) {
        UnsafeMemoryInput unsafeInput = (UnsafeMemoryInput)input;
        unsafeInput.readBytes(object, offset, len);
      } else {
        readSlow(input, object);
      }
    }

    /*** This is a fall-back solution for the case that bulk reading of bytes into object memory is not supported. Unfortunately,
     * current Oracle JDKs do not allow for bulk reading in this style due to problems with GC.
     *
     * @param input
     * @param object */
    private void readSlow (Input input, Object object) {
      long off;
      Unsafe unsafe = unsafe();
      for (off = offset; off < offset + len - 8; off += 8) {
        unsafe.putLong(object, off, input.readLong());
      }

      if (off < offset + len) {
        for (; off < offset + len; ++off) {
          unsafe.putByte(object, off, input.readByte());
        }
      }
    }

    public void copy (Object original, Object copy) {
      unsafe().copyMemory(original, offset, copy, offset, len);
    }
  }

  final static class UnsafeObjectField extends ObjectField {
    public UnsafeObjectField (FieldSerializer fieldSerializer) {
      super(fieldSerializer);
    }

    public Object getField (Object object) throws IllegalArgumentException, IllegalAccessException {
      if (offset >= 0) {
        return unsafe().getObject(object, offset);
      } else
        throw new KryoException("Unknown offset");
    }

    public void setField (Object object, Object value) throws IllegalArgumentException, IllegalAccessException {
      if (offset != -1)
        unsafe().putObject(object, offset, value);
      else
        throw new KryoException("Unknown offset");
    }

    public void copy (Object original, Object copy) {
      try {
        if (offset != -1) {
          unsafe().putObject(copy, offset, kryo.copy(unsafe().getObject(original, offset)));
        } else
          throw new KryoException("Unknown offset");
      } catch (KryoException ex) {
        ex.addTrace(this + " (" + type.getName() + ")");
        throw ex;
      } catch (RuntimeException runtimeEx) {
        KryoException ex = new KryoException(runtimeEx);
        ex.addTrace(this + " (" + type.getName() + ")");
        throw ex;
      }
    }
  }
}
TOP

Related Classes of com.esotericsoftware.kryo.serializers.UnsafeCacheFields$UnsafeStringField

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.