/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
/**
 * Autogenerated by Thrift Compiler (0.9.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.accumulo.proxy.thrift;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"unchecked", "serial", "rawtypes", "unused"}) public class WriterOptions implements org.apache.thrift.TBase<WriterOptions, WriterOptions._Fields>, java.io.Serializable, Cloneable, Comparable<WriterOptions> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("WriterOptions");

  private static final org.apache.thrift.protocol.TField MAX_MEMORY_FIELD_DESC = new org.apache.thrift.protocol.TField("maxMemory", org.apache.thrift.protocol.TType.I64, (short)1);
  private static final org.apache.thrift.protocol.TField LATENCY_MS_FIELD_DESC = new org.apache.thrift.protocol.TField("latencyMs", org.apache.thrift.protocol.TType.I64, (short)2);
  private static final org.apache.thrift.protocol.TField TIMEOUT_MS_FIELD_DESC = new org.apache.thrift.protocol.TField("timeoutMs", org.apache.thrift.protocol.TType.I64, (short)3);
  private static final org.apache.thrift.protocol.TField THREADS_FIELD_DESC = new org.apache.thrift.protocol.TField("threads", org.apache.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.thrift.protocol.TField DURABILITY_FIELD_DESC = new org.apache.thrift.protocol.TField("durability", org.apache.thrift.protocol.TType.I32, (short)5);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new WriterOptionsStandardSchemeFactory());
    schemes.put(TupleScheme.class, new WriterOptionsTupleSchemeFactory());
  }

  public long maxMemory; // required
  public long latencyMs; // required
  public long timeoutMs; // required
  public int threads; // required
  /**
   * 
   * @see Durability
   */
  public Durability durability; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    MAX_MEMORY((short)1, "maxMemory"),
    LATENCY_MS((short)2, "latencyMs"),
    TIMEOUT_MS((short)3, "timeoutMs"),
    THREADS((short)4, "threads"),
    /**
     * 
     * @see Durability
     */
    DURABILITY((short)5, "durability");

    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

    static {
      for (_Fields field : EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // MAX_MEMORY
          return MAX_MEMORY;
        case 2: // LATENCY_MS
          return LATENCY_MS;
        case 3: // TIMEOUT_MS
          return TIMEOUT_MS;
        case 4: // THREADS
          return THREADS;
        case 5: // DURABILITY
          return DURABILITY;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

    _Fields(short thriftId, String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __MAXMEMORY_ISSET_ID = 0;
  private static final int __LATENCYMS_ISSET_ID = 1;
  private static final int __TIMEOUTMS_ISSET_ID = 2;
  private static final int __THREADS_ISSET_ID = 3;
  private byte __isset_bitfield = 0;
  private _Fields optionals[] = {_Fields.DURABILITY};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.MAX_MEMORY, new org.apache.thrift.meta_data.FieldMetaData("maxMemory", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.LATENCY_MS, new org.apache.thrift.meta_data.FieldMetaData("latencyMs", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.TIMEOUT_MS, new org.apache.thrift.meta_data.FieldMetaData("timeoutMs", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.THREADS, new org.apache.thrift.meta_data.FieldMetaData("threads", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.DURABILITY, new org.apache.thrift.meta_data.FieldMetaData("durability", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, Durability.class)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WriterOptions.class, metaDataMap);
  }

  public WriterOptions() {
  }

  public WriterOptions(
    long maxMemory,
    long latencyMs,
    long timeoutMs,
    int threads)
  {
    this();
    this.maxMemory = maxMemory;
    setMaxMemoryIsSet(true);
    this.latencyMs = latencyMs;
    setLatencyMsIsSet(true);
    this.timeoutMs = timeoutMs;
    setTimeoutMsIsSet(true);
    this.threads = threads;
    setThreadsIsSet(true);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public WriterOptions(WriterOptions other) {
    __isset_bitfield = other.__isset_bitfield;
    this.maxMemory = other.maxMemory;
    this.latencyMs = other.latencyMs;
    this.timeoutMs = other.timeoutMs;
    this.threads = other.threads;
    if (other.isSetDurability()) {
      this.durability = other.durability;
    }
  }

  public WriterOptions deepCopy() {
    return new WriterOptions(this);
  }

  @Override
  public void clear() {
    setMaxMemoryIsSet(false);
    this.maxMemory = 0;
    setLatencyMsIsSet(false);
    this.latencyMs = 0;
    setTimeoutMsIsSet(false);
    this.timeoutMs = 0;
    setThreadsIsSet(false);
    this.threads = 0;
    this.durability = null;
  }

  public long getMaxMemory() {
    return this.maxMemory;
  }

  public WriterOptions setMaxMemory(long maxMemory) {
    this.maxMemory = maxMemory;
    setMaxMemoryIsSet(true);
    return this;
  }

  public void unsetMaxMemory() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
  }

  /** Returns true if field maxMemory is set (has been assigned a value) and false otherwise */
  public boolean isSetMaxMemory() {
    return EncodingUtils.testBit(__isset_bitfield, __MAXMEMORY_ISSET_ID);
  }

  public void setMaxMemoryIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __MAXMEMORY_ISSET_ID, value);
  }

  public long getLatencyMs() {
    return this.latencyMs;
  }

  public WriterOptions setLatencyMs(long latencyMs) {
    this.latencyMs = latencyMs;
    setLatencyMsIsSet(true);
    return this;
  }

  public void unsetLatencyMs() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __LATENCYMS_ISSET_ID);
  }

  /** Returns true if field latencyMs is set (has been assigned a value) and false otherwise */
  public boolean isSetLatencyMs() {
    return EncodingUtils.testBit(__isset_bitfield, __LATENCYMS_ISSET_ID);
  }

  public void setLatencyMsIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __LATENCYMS_ISSET_ID, value);
  }

  public long getTimeoutMs() {
    return this.timeoutMs;
  }

  public WriterOptions setTimeoutMs(long timeoutMs) {
    this.timeoutMs = timeoutMs;
    setTimeoutMsIsSet(true);
    return this;
  }

  public void unsetTimeoutMs() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
  }

  /** Returns true if field timeoutMs is set (has been assigned a value) and false otherwise */
  public boolean isSetTimeoutMs() {
    return EncodingUtils.testBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID);
  }

  public void setTimeoutMsIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TIMEOUTMS_ISSET_ID, value);
  }

  public int getThreads() {
    return this.threads;
  }

  public WriterOptions setThreads(int threads) {
    this.threads = threads;
    setThreadsIsSet(true);
    return this;
  }

  public void unsetThreads() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __THREADS_ISSET_ID);
  }

  /** Returns true if field threads is set (has been assigned a value) and false otherwise */
  public boolean isSetThreads() {
    return EncodingUtils.testBit(__isset_bitfield, __THREADS_ISSET_ID);
  }

  public void setThreadsIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __THREADS_ISSET_ID, value);
  }

  /**
   * 
   * @see Durability
   */
  public Durability getDurability() {
    return this.durability;
  }

  /**
   * 
   * @see Durability
   */
  public WriterOptions setDurability(Durability durability) {
    this.durability = durability;
    return this;
  }

  public void unsetDurability() {
    this.durability = null;
  }

  /** Returns true if field durability is set (has been assigned a value) and false otherwise */
  public boolean isSetDurability() {
    return this.durability != null;
  }

  public void setDurabilityIsSet(boolean value) {
    if (!value) {
      this.durability = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case MAX_MEMORY:
      if (value == null) {
        unsetMaxMemory();
      } else {
        setMaxMemory((Long)value);
      }
      break;

    case LATENCY_MS:
      if (value == null) {
        unsetLatencyMs();
      } else {
        setLatencyMs((Long)value);
      }
      break;

    case TIMEOUT_MS:
      if (value == null) {
        unsetTimeoutMs();
      } else {
        setTimeoutMs((Long)value);
      }
      break;

    case THREADS:
      if (value == null) {
        unsetThreads();
      } else {
        setThreads((Integer)value);
      }
      break;

    case DURABILITY:
      if (value == null) {
        unsetDurability();
      } else {
        setDurability((Durability)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case MAX_MEMORY:
      return Long.valueOf(getMaxMemory());

    case LATENCY_MS:
      return Long.valueOf(getLatencyMs());

    case TIMEOUT_MS:
      return Long.valueOf(getTimeoutMs());

    case THREADS:
      return Integer.valueOf(getThreads());

    case DURABILITY:
      return getDurability();

    }
    throw new IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new IllegalArgumentException();
    }

    switch (field) {
    case MAX_MEMORY:
      return isSetMaxMemory();
    case LATENCY_MS:
      return isSetLatencyMs();
    case TIMEOUT_MS:
      return isSetTimeoutMs();
    case THREADS:
      return isSetThreads();
    case DURABILITY:
      return isSetDurability();
    }
    throw new IllegalStateException();
  }

  @Override
  public boolean equals(Object that) {
    if (that == null)
      return false;
    if (that instanceof WriterOptions)
      return this.equals((WriterOptions)that);
    return false;
  }

  public boolean equals(WriterOptions that) {
    if (that == null)
      return false;

    boolean this_present_maxMemory = true;
    boolean that_present_maxMemory = true;
    if (this_present_maxMemory || that_present_maxMemory) {
      if (!(this_present_maxMemory && that_present_maxMemory))
        return false;
      if (this.maxMemory != that.maxMemory)
        return false;
    }

    boolean this_present_latencyMs = true;
    boolean that_present_latencyMs = true;
    if (this_present_latencyMs || that_present_latencyMs) {
      if (!(this_present_latencyMs && that_present_latencyMs))
        return false;
      if (this.latencyMs != that.latencyMs)
        return false;
    }

    boolean this_present_timeoutMs = true;
    boolean that_present_timeoutMs = true;
    if (this_present_timeoutMs || that_present_timeoutMs) {
      if (!(this_present_timeoutMs && that_present_timeoutMs))
        return false;
      if (this.timeoutMs != that.timeoutMs)
        return false;
    }

    boolean this_present_threads = true;
    boolean that_present_threads = true;
    if (this_present_threads || that_present_threads) {
      if (!(this_present_threads && that_present_threads))
        return false;
      if (this.threads != that.threads)
        return false;
    }

    boolean this_present_durability = true && this.isSetDurability();
    boolean that_present_durability = true && that.isSetDurability();
    if (this_present_durability || that_present_durability) {
      if (!(this_present_durability && that_present_durability))
        return false;
      if (!this.durability.equals(that.durability))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    return 0;
  }

  @Override
  public int compareTo(WriterOptions other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetMaxMemory()).compareTo(other.isSetMaxMemory());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMaxMemory()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.maxMemory, other.maxMemory);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetLatencyMs()).compareTo(other.isSetLatencyMs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLatencyMs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.latencyMs, other.latencyMs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTimeoutMs()).compareTo(other.isSetTimeoutMs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTimeoutMs()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timeoutMs, other.timeoutMs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetThreads()).compareTo(other.isSetThreads());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetThreads()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.threads, other.threads);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetDurability()).compareTo(other.isSetDurability());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetDurability()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.durability, other.durability);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("WriterOptions(");
    boolean first = true;

    sb.append("maxMemory:");
    sb.append(this.maxMemory);
    first = false;
    if (!first) sb.append(", ");
    sb.append("latencyMs:");
    sb.append(this.latencyMs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("timeoutMs:");
    sb.append(this.timeoutMs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("threads:");
    sb.append(this.threads);
    first = false;
    if (isSetDurability()) {
      if (!first) sb.append(", ");
      sb.append("durability:");
      if (this.durability == null) {
        sb.append("null");
      } else {
        sb.append(this.durability);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class WriterOptionsStandardSchemeFactory implements SchemeFactory {
    public WriterOptionsStandardScheme getScheme() {
      return new WriterOptionsStandardScheme();
    }
  }

  private static class WriterOptionsStandardScheme extends StandardScheme<WriterOptions> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, WriterOptions struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // MAX_MEMORY
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.maxMemory = iprot.readI64();
              struct.setMaxMemoryIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // LATENCY_MS
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.latencyMs = iprot.readI64();
              struct.setLatencyMsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TIMEOUT_MS
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.timeoutMs = iprot.readI64();
              struct.setTimeoutMsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // THREADS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.threads = iprot.readI32();
              struct.setThreadsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // DURABILITY
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.durability = Durability.findByValue(iprot.readI32());
              struct.setDurabilityIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, WriterOptions struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(MAX_MEMORY_FIELD_DESC);
      oprot.writeI64(struct.maxMemory);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(LATENCY_MS_FIELD_DESC);
      oprot.writeI64(struct.latencyMs);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(TIMEOUT_MS_FIELD_DESC);
      oprot.writeI64(struct.timeoutMs);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(THREADS_FIELD_DESC);
      oprot.writeI32(struct.threads);
      oprot.writeFieldEnd();
      if (struct.durability != null) {
        if (struct.isSetDurability()) {
          oprot.writeFieldBegin(DURABILITY_FIELD_DESC);
          oprot.writeI32(struct.durability.getValue());
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class WriterOptionsTupleSchemeFactory implements SchemeFactory {
    public WriterOptionsTupleScheme getScheme() {
      return new WriterOptionsTupleScheme();
    }
  }

  private static class WriterOptionsTupleScheme extends TupleScheme<WriterOptions> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, WriterOptions struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetMaxMemory()) {
        optionals.set(0);
      }
      if (struct.isSetLatencyMs()) {
        optionals.set(1);
      }
      if (struct.isSetTimeoutMs()) {
        optionals.set(2);
      }
      if (struct.isSetThreads()) {
        optionals.set(3);
      }
      if (struct.isSetDurability()) {
        optionals.set(4);
      }
      oprot.writeBitSet(optionals, 5);
      if (struct.isSetMaxMemory()) {
        oprot.writeI64(struct.maxMemory);
      }
      if (struct.isSetLatencyMs()) {
        oprot.writeI64(struct.latencyMs);
      }
      if (struct.isSetTimeoutMs()) {
        oprot.writeI64(struct.timeoutMs);
      }
      if (struct.isSetThreads()) {
        oprot.writeI32(struct.threads);
      }
      if (struct.isSetDurability()) {
        oprot.writeI32(struct.durability.getValue());
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, WriterOptions struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(5);
      if (incoming.get(0)) {
        struct.maxMemory = iprot.readI64();
        struct.setMaxMemoryIsSet(true);
      }
      if (incoming.get(1)) {
        struct.latencyMs = iprot.readI64();
        struct.setLatencyMsIsSet(true);
      }
      if (incoming.get(2)) {
        struct.timeoutMs = iprot.readI64();
        struct.setTimeoutMsIsSet(true);
      }
      if (incoming.get(3)) {
        struct.threads = iprot.readI32();
        struct.setThreadsIsSet(true);
      }
      if (incoming.get(4)) {
        struct.durability = Durability.findByValue(iprot.readI32());
        struct.setDurabilityIsSet(true);
      }
    }
  }

}

