public void flattenToBuffer(ByteBuffer buf) throws IOException {
   assert (!((params == null) && (serializedParams == null)));
   assert ((params != null) || (serializedParams != null));
   buf.put(type.getValue()); // version and type
   if (ProcedureInvocationType.isDeprecatedInternalDRType(type)) {
     buf.putLong(originalTxnId);
     buf.putLong(originalUniqueId);
   }
   if (type.getValue() >= BatchTimeoutOverrideType.BATCH_TIMEOUT_VERSION) {
     if (batchTimeout == BatchTimeoutOverrideType.NO_TIMEOUT) {
       buf.put(BatchTimeoutOverrideType.NO_OVERRIDE_FOR_BATCH_TIMEOUT.getValue());
     } else {
       buf.put(BatchTimeoutOverrideType.HAS_OVERRIDE_FOR_BATCH_TIMEOUT.getValue());
       buf.putInt(batchTimeout);
     }
   }
   buf.putInt(procName.length());
   buf.put(procName.getBytes(Constants.UTF8ENCODING));
   buf.putLong(clientHandle);
   if (serializedParams != null) {
     if (serializedParams.hasArray()) {
       // if position can be non-zero, then the dup/rewind logic below
       // would be wrong?
       assert (serializedParams.position() == 0);
       buf.put(
           serializedParams.array(),
           serializedParams.position() + serializedParams.arrayOffset(),
           serializedParams.remaining());
     } else {
       // duplicate for thread-safety
       assert (serializedParams.position() == 0);
       ByteBuffer dup = serializedParams.duplicate();
       dup.rewind();
       buf.put(dup);
     }
   } else if (params != null) {
     try {
       getParams().flattenToBuffer(buf);
     } catch (BufferOverflowException e) {
       hostLog.info("SP \"" + procName + "\" has thrown BufferOverflowException");
       hostLog.info(toString());
       throw e;
     }
   }
 }
  public void initFromBuffer(ByteBuffer buf) throws IOException {
    FastDeserializer in = new FastDeserializer(buf);
    byte version = in.readByte(); // version number also embeds the type
    type = ProcedureInvocationType.typeFromByte(version);

    /*
     * If it's a replicated invocation, there should be two txn IDs
     * following the version byte. The first txn ID is the new txn ID, the
     * second one is the original txn ID.
     */
    if (ProcedureInvocationType.isDeprecatedInternalDRType(type)) {
      originalTxnId = in.readLong();
      originalUniqueId = in.readLong();
    }

    if (version >= BatchTimeoutOverrideType.BATCH_TIMEOUT_VERSION) {
      BatchTimeoutOverrideType batchTimeoutType =
          BatchTimeoutOverrideType.typeFromByte(in.readByte());
      if (batchTimeoutType == BatchTimeoutOverrideType.NO_OVERRIDE_FOR_BATCH_TIMEOUT) {
        batchTimeout = BatchTimeoutOverrideType.NO_TIMEOUT;
      } else {
        batchTimeout = in.readInt();
        // Client side have already checked the batchTimeout value, but,
        // on server side, we should check non-negative batchTimeout value again
        // in case of someone is using a non-standard client.
        if (batchTimeout < 0) {
          throw new IllegalArgumentException("Timeout value can't be negative.");
        }
      }
    }

    procName = in.readString().intern();
    clientHandle = in.readLong();
    // do not deserialize parameters in ClientInterface context
    serializedParams = in.remainder();
    final ByteBuffer duplicate = serializedParams.duplicate();
    params =
        new FutureTask<ParameterSet>(
            new Callable<ParameterSet>() {
              @Override
              public ParameterSet call() throws Exception {
                return ParameterSet.fromByteBuffer(duplicate);
              }
            });
  }
 public void getDumpContents(StringBuilder sb) {
   sb.append(type.name()).append("Invocation: ").append(procName).append("(");
   ParameterSet params = getParams();
   if (params != null)
     for (Object o : params.toArray()) {
       sb.append(o.toString()).append(", ");
     }
   else sb.append("null");
   sb.append(")");
 }
  public int getSerializedSize() {
    int timeoutSize = 0;
    if (type.getValue() >= BatchTimeoutOverrideType.BATCH_TIMEOUT_VERSION) {
      timeoutSize = 1 + (batchTimeout == BatchTimeoutOverrideType.NO_TIMEOUT ? 0 : 4);
    }

    int size =
        1 // Version/type
            + timeoutSize // batch time out byte
            + 4 // proc name string length
            + procName.length()
            + 8; // clientHandle

    if (ProcedureInvocationType.isDeprecatedInternalDRType(type)) {
      size +=
          8 + // original TXN ID for WAN replication procedures
              8; // original timestamp for WAN replication procedures
    }

    if (serializedParams != null) {
      size += serializedParams.remaining();
    } else if (params != null) {
      ParameterSet pset = getParams();
      assert (pset != null);
      int serializedSize = pset.getSerializedSize();
      if ((pset.size() > 0) && (serializedSize <= 2)) {
        throw new IllegalStateException(
            String.format(
                "Parameter set for invocation "
                    + "%s doesn't have the proper size (currently = %s)",
                getProcName(), serializedSize));
      }
      size += pset.getSerializedSize();
    }

    return size;
  }
  @Override
  public String toString() {
    String retval = type.name() + " Invocation: " + procName + "(";
    ParameterSet params = getParams();
    if (params != null)
      for (Object o : params.toArray()) {
        retval += String.valueOf(o) + ", ";
      }
    else retval += "null";
    retval += ")";
    retval += " type=" + String.valueOf(type);
    retval += " batchTimeout=" + BatchTimeoutOverrideType.toString(batchTimeout);
    retval += " clientHandle=" + String.valueOf(clientHandle);
    retval += " originalTxnId=" + String.valueOf(originalTxnId);
    retval += " originalUniqueId=" + String.valueOf(originalUniqueId);

    return retval;
  }