Package org.tarantool.core.impl

Source Code of org.tarantool.core.impl.OperationImpl

package org.tarantool.core.impl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.tarantool.core.Operation;
import org.tarantool.core.Tuple;
import org.tarantool.core.proto.Leb128;
import org.tarantool.core.proto.Updates;

/**
* <p>
* OperationImpl class.
* </p>
*
* @author dgreen
* @version $Id: $
*/
public class OperationImpl extends Operation {
  /**
   * Creates update operation
   *
   * @param op
   *            Update operation {@link org.tarantool.core.proto.Updates}
   * @param fieldNo
   *            Number of field to execute update. Remember that Tarantool
   *            supports only 3 data types: integer, long and byte[]. So
   *            arithmetic operations can only be executed on integer and long
   *            elements.
   * @param args
   *            Operation arguments. usually there should be 1 argument, but
   *            SPLICE has 3
   */
  public OperationImpl(Updates op, int fieldNo, Tuple args) {
    this.op = op;
    this.fieldNo = fieldNo;
    this.args = args;
    if (args.size() != op.args) {
      throw new IllegalArgumentException(op.name() + " required " + op.args + " arguments but has " + args.size());
    }
  }

  Updates op;
  int fieldNo;
  Tuple args;

  /**
   * <p>
   * Getter for the field <code>op</code>.
   * </p>
   *
   * @return a {@link org.tarantool.core.proto.Updates} object.
   */
  public Updates getOp() {
    return op;
  }

  /**
   * <p>
   * Setter for the field <code>op</code>.
   * </p>
   *
   * @param op
   *            a {@link org.tarantool.core.proto.Updates} object.
   */
  public void setOp(Updates op) {
    this.op = op;
  }

  /**
   * <p>
   * Getter for the field <code>fieldNo</code>.
   * </p>
   *
   * @return a int.
   */
  public int getFieldNo() {
    return fieldNo;
  }

  /**
   * <p>
   * Setter for the field <code>fieldNo</code>.
   * </p>
   *
   * @param fieldNo
   *            a int.
   */
  public void setFieldNo(int fieldNo) {
    this.fieldNo = fieldNo;
  }

  /**
   * <p>
   * Getter for the field <code>args</code>.
   * </p>
   *
   * @return a {@link org.tarantool.core.Tuple} object.
   */
  public Tuple getArgs() {
    return args;
  }

  /**
   * <p>
   * Setter for the field <code>args</code>.
   * </p>
   *
   * @param args
   *            a {@link org.tarantool.core.Tuple} object.
   */
  public void setArgs(Tuple args) {
    this.args = args;
  }

  /**
   * <p>
   * pack.
   * </p>
   *
   * @return an array of byte.
   */
  public byte[] pack() {
    int fieldsSize = args.calcFieldsSize();
    int multiFieldOffset = args.size() > 1 ? Leb128.unsignedSize(fieldsSize) : 0;
    ByteBuffer buf = ByteBuffer.allocate(5 + fieldsSize + multiFieldOffset).order(ByteOrder.LITTLE_ENDIAN);
    buf.putInt(fieldNo);
    buf.put((byte) op.type);
    if (args.size() > 1) {
      Leb128.writeUnsigned(buf, fieldsSize);
    }
    return args.packFields(buf);
  }

  public static OperationImpl unpack(ByteBuffer buffer) {
    int fieldNo = buffer.getInt();
    byte type = buffer.get();
    Updates[] ups = Updates.values();
    Updates update = null;
    for (Updates up : ups) {
      if (up.type == (int) type) {
        update = up;
        break;
      }
    }
    if (update == null) {
      throw new IllegalStateException("Unknown update op type " + type);
    }
    if (update.args > 1) {
      int fields = Leb128.readUnsigned(buffer);
      if (fields != update.args) {
        throw new IllegalStateException("op " + update.name() + " should has " + update.args + " arguments, but has " + fields);
      }
    }
    Tuple opArgs = Tuple.createFromPackedFields(buffer, ByteOrder.LITTLE_ENDIAN, update.args);
    return new OperationImpl(update, fieldNo, opArgs);
  }

}
TOP

Related Classes of org.tarantool.core.impl.OperationImpl

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.