/**
 * 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.13.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.storm.generated;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.13.0)")
public class RebalanceOptions implements org.apache.storm.thrift.TBase<RebalanceOptions, RebalanceOptions._Fields>, java.io.Serializable, Cloneable, Comparable<RebalanceOptions> {
  private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("RebalanceOptions");

  private static final org.apache.storm.thrift.protocol.TField WAIT_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("wait_secs", org.apache.storm.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.storm.thrift.protocol.TField NUM_WORKERS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("num_workers", org.apache.storm.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.storm.thrift.protocol.TField NUM_EXECUTORS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("num_executors", org.apache.storm.thrift.protocol.TType.MAP, (short)3);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_RESOURCES_OVERRIDES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_resources_overrides", org.apache.storm.thrift.protocol.TType.MAP, (short)4);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_CONF_OVERRIDES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_conf_overrides", org.apache.storm.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.storm.thrift.protocol.TField PRINCIPAL_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("principal", org.apache.storm.thrift.protocol.TType.STRING, (short)6);

  private static final org.apache.storm.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new RebalanceOptionsStandardSchemeFactory();
  private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new RebalanceOptionsTupleSchemeFactory();

  private int wait_secs; // optional
  private int num_workers; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Integer> num_executors; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>> topology_resources_overrides; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_conf_overrides; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String principal; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
    WAIT_SECS((short)1, "wait_secs"),
    NUM_WORKERS((short)2, "num_workers"),
    NUM_EXECUTORS((short)3, "num_executors"),
    TOPOLOGY_RESOURCES_OVERRIDES((short)4, "topology_resources_overrides"),
    TOPOLOGY_CONF_OVERRIDES((short)5, "topology_conf_overrides"),
    PRINCIPAL((short)6, "principal");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.storm.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // WAIT_SECS
          return WAIT_SECS;
        case 2: // NUM_WORKERS
          return NUM_WORKERS;
        case 3: // NUM_EXECUTORS
          return NUM_EXECUTORS;
        case 4: // TOPOLOGY_RESOURCES_OVERRIDES
          return TOPOLOGY_RESOURCES_OVERRIDES;
        case 5: // TOPOLOGY_CONF_OVERRIDES
          return TOPOLOGY_CONF_OVERRIDES;
        case 6: // PRINCIPAL
          return PRINCIPAL;
        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 java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    @org.apache.storm.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __WAIT_SECS_ISSET_ID = 0;
  private static final int __NUM_WORKERS_ISSET_ID = 1;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.WAIT_SECS,_Fields.NUM_WORKERS,_Fields.NUM_EXECUTORS,_Fields.TOPOLOGY_RESOURCES_OVERRIDES,_Fields.TOPOLOGY_CONF_OVERRIDES,_Fields.PRINCIPAL};
  public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.WAIT_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("wait_secs", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NUM_WORKERS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_workers", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NUM_EXECUTORS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_executors", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32))));
    tmpMap.put(_Fields.TOPOLOGY_RESOURCES_OVERRIDES, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_resources_overrides", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)))));
    tmpMap.put(_Fields.TOPOLOGY_CONF_OVERRIDES, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_conf_overrides", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PRINCIPAL, new org.apache.storm.thrift.meta_data.FieldMetaData("principal", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RebalanceOptions.class, metaDataMap);
  }

  public RebalanceOptions() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public RebalanceOptions(RebalanceOptions other) {
    __isset_bitfield = other.__isset_bitfield;
    this.wait_secs = other.wait_secs;
    this.num_workers = other.num_workers;
    if (other.is_set_num_executors()) {
      java.util.Map<java.lang.String,java.lang.Integer> __this__num_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>(other.num_executors);
      this.num_executors = __this__num_executors;
    }
    if (other.is_set_topology_resources_overrides()) {
      java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>> __this__topology_resources_overrides = new java.util.HashMap<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>>(other.topology_resources_overrides.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Map<java.lang.String,java.lang.Double>> other_element : other.topology_resources_overrides.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Map<java.lang.String,java.lang.Double> other_element_value = other_element.getValue();

        java.lang.String __this__topology_resources_overrides_copy_key = other_element_key;

        java.util.Map<java.lang.String,java.lang.Double> __this__topology_resources_overrides_copy_value = new java.util.HashMap<java.lang.String,java.lang.Double>(other_element_value);

        __this__topology_resources_overrides.put(__this__topology_resources_overrides_copy_key, __this__topology_resources_overrides_copy_value);
      }
      this.topology_resources_overrides = __this__topology_resources_overrides;
    }
    if (other.is_set_topology_conf_overrides()) {
      this.topology_conf_overrides = other.topology_conf_overrides;
    }
    if (other.is_set_principal()) {
      this.principal = other.principal;
    }
  }

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

  @Override
  public void clear() {
    set_wait_secs_isSet(false);
    this.wait_secs = 0;
    set_num_workers_isSet(false);
    this.num_workers = 0;
    this.num_executors = null;
    this.topology_resources_overrides = null;
    this.topology_conf_overrides = null;
    this.principal = null;
  }

  public int get_wait_secs() {
    return this.wait_secs;
  }

  public void set_wait_secs(int wait_secs) {
    this.wait_secs = wait_secs;
    set_wait_secs_isSet(true);
  }

  public void unset_wait_secs() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __WAIT_SECS_ISSET_ID);
  }

  /** Returns true if field wait_secs is set (has been assigned a value) and false otherwise */
  public boolean is_set_wait_secs() {
    return org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __WAIT_SECS_ISSET_ID);
  }

  public void set_wait_secs_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __WAIT_SECS_ISSET_ID, value);
  }

  public int get_num_workers() {
    return this.num_workers;
  }

  public void set_num_workers(int num_workers) {
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
  }

  public void unset_num_workers() {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.clearBit(__isset_bitfield, __NUM_WORKERS_ISSET_ID);
  }

  /** Returns true if field num_workers is set (has been assigned a value) and false otherwise */
  public boolean is_set_num_workers() {
    return org.apache.storm.thrift.EncodingUtils.testBit(__isset_bitfield, __NUM_WORKERS_ISSET_ID);
  }

  public void set_num_workers_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __NUM_WORKERS_ISSET_ID, value);
  }

  public int get_num_executors_size() {
    return (this.num_executors == null) ? 0 : this.num_executors.size();
  }

  public void put_to_num_executors(java.lang.String key, int val) {
    if (this.num_executors == null) {
      this.num_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>();
    }
    this.num_executors.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,java.lang.Integer> get_num_executors() {
    return this.num_executors;
  }

  public void set_num_executors(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Integer> num_executors) {
    this.num_executors = num_executors;
  }

  public void unset_num_executors() {
    this.num_executors = null;
  }

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

  public void set_num_executors_isSet(boolean value) {
    if (!value) {
      this.num_executors = null;
    }
  }

  public int get_topology_resources_overrides_size() {
    return (this.topology_resources_overrides == null) ? 0 : this.topology_resources_overrides.size();
  }

  public void put_to_topology_resources_overrides(java.lang.String key, java.util.Map<java.lang.String,java.lang.Double> val) {
    if (this.topology_resources_overrides == null) {
      this.topology_resources_overrides = new java.util.HashMap<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>>();
    }
    this.topology_resources_overrides.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>> get_topology_resources_overrides() {
    return this.topology_resources_overrides;
  }

  public void set_topology_resources_overrides(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>> topology_resources_overrides) {
    this.topology_resources_overrides = topology_resources_overrides;
  }

  public void unset_topology_resources_overrides() {
    this.topology_resources_overrides = null;
  }

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

  public void set_topology_resources_overrides_isSet(boolean value) {
    if (!value) {
      this.topology_resources_overrides = null;
    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.String get_topology_conf_overrides() {
    return this.topology_conf_overrides;
  }

  public void set_topology_conf_overrides(@org.apache.storm.thrift.annotation.Nullable java.lang.String topology_conf_overrides) {
    this.topology_conf_overrides = topology_conf_overrides;
  }

  public void unset_topology_conf_overrides() {
    this.topology_conf_overrides = null;
  }

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

  public void set_topology_conf_overrides_isSet(boolean value) {
    if (!value) {
      this.topology_conf_overrides = null;
    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.String get_principal() {
    return this.principal;
  }

  public void set_principal(@org.apache.storm.thrift.annotation.Nullable java.lang.String principal) {
    this.principal = principal;
  }

  public void unset_principal() {
    this.principal = null;
  }

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

  public void set_principal_isSet(boolean value) {
    if (!value) {
      this.principal = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case WAIT_SECS:
      if (value == null) {
        unset_wait_secs();
      } else {
        set_wait_secs((java.lang.Integer)value);
      }
      break;

    case NUM_WORKERS:
      if (value == null) {
        unset_num_workers();
      } else {
        set_num_workers((java.lang.Integer)value);
      }
      break;

    case NUM_EXECUTORS:
      if (value == null) {
        unset_num_executors();
      } else {
        set_num_executors((java.util.Map<java.lang.String,java.lang.Integer>)value);
      }
      break;

    case TOPOLOGY_RESOURCES_OVERRIDES:
      if (value == null) {
        unset_topology_resources_overrides();
      } else {
        set_topology_resources_overrides((java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>>)value);
      }
      break;

    case TOPOLOGY_CONF_OVERRIDES:
      if (value == null) {
        unset_topology_conf_overrides();
      } else {
        set_topology_conf_overrides((java.lang.String)value);
      }
      break;

    case PRINCIPAL:
      if (value == null) {
        unset_principal();
      } else {
        set_principal((java.lang.String)value);
      }
      break;

    }
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case WAIT_SECS:
      return get_wait_secs();

    case NUM_WORKERS:
      return get_num_workers();

    case NUM_EXECUTORS:
      return get_num_executors();

    case TOPOLOGY_RESOURCES_OVERRIDES:
      return get_topology_resources_overrides();

    case TOPOLOGY_CONF_OVERRIDES:
      return get_topology_conf_overrides();

    case PRINCIPAL:
      return get_principal();

    }
    throw new java.lang.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 java.lang.IllegalArgumentException();
    }

    switch (field) {
    case WAIT_SECS:
      return is_set_wait_secs();
    case NUM_WORKERS:
      return is_set_num_workers();
    case NUM_EXECUTORS:
      return is_set_num_executors();
    case TOPOLOGY_RESOURCES_OVERRIDES:
      return is_set_topology_resources_overrides();
    case TOPOLOGY_CONF_OVERRIDES:
      return is_set_topology_conf_overrides();
    case PRINCIPAL:
      return is_set_principal();
    }
    throw new java.lang.IllegalStateException();
  }

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

  public boolean equals(RebalanceOptions that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_wait_secs = true && this.is_set_wait_secs();
    boolean that_present_wait_secs = true && that.is_set_wait_secs();
    if (this_present_wait_secs || that_present_wait_secs) {
      if (!(this_present_wait_secs && that_present_wait_secs))
        return false;
      if (this.wait_secs != that.wait_secs)
        return false;
    }

    boolean this_present_num_workers = true && this.is_set_num_workers();
    boolean that_present_num_workers = true && that.is_set_num_workers();
    if (this_present_num_workers || that_present_num_workers) {
      if (!(this_present_num_workers && that_present_num_workers))
        return false;
      if (this.num_workers != that.num_workers)
        return false;
    }

    boolean this_present_num_executors = true && this.is_set_num_executors();
    boolean that_present_num_executors = true && that.is_set_num_executors();
    if (this_present_num_executors || that_present_num_executors) {
      if (!(this_present_num_executors && that_present_num_executors))
        return false;
      if (!this.num_executors.equals(that.num_executors))
        return false;
    }

    boolean this_present_topology_resources_overrides = true && this.is_set_topology_resources_overrides();
    boolean that_present_topology_resources_overrides = true && that.is_set_topology_resources_overrides();
    if (this_present_topology_resources_overrides || that_present_topology_resources_overrides) {
      if (!(this_present_topology_resources_overrides && that_present_topology_resources_overrides))
        return false;
      if (!this.topology_resources_overrides.equals(that.topology_resources_overrides))
        return false;
    }

    boolean this_present_topology_conf_overrides = true && this.is_set_topology_conf_overrides();
    boolean that_present_topology_conf_overrides = true && that.is_set_topology_conf_overrides();
    if (this_present_topology_conf_overrides || that_present_topology_conf_overrides) {
      if (!(this_present_topology_conf_overrides && that_present_topology_conf_overrides))
        return false;
      if (!this.topology_conf_overrides.equals(that.topology_conf_overrides))
        return false;
    }

    boolean this_present_principal = true && this.is_set_principal();
    boolean that_present_principal = true && that.is_set_principal();
    if (this_present_principal || that_present_principal) {
      if (!(this_present_principal && that_present_principal))
        return false;
      if (!this.principal.equals(that.principal))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((is_set_wait_secs()) ? 131071 : 524287);
    if (is_set_wait_secs())
      hashCode = hashCode * 8191 + wait_secs;

    hashCode = hashCode * 8191 + ((is_set_num_workers()) ? 131071 : 524287);
    if (is_set_num_workers())
      hashCode = hashCode * 8191 + num_workers;

    hashCode = hashCode * 8191 + ((is_set_num_executors()) ? 131071 : 524287);
    if (is_set_num_executors())
      hashCode = hashCode * 8191 + num_executors.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_resources_overrides()) ? 131071 : 524287);
    if (is_set_topology_resources_overrides())
      hashCode = hashCode * 8191 + topology_resources_overrides.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_conf_overrides()) ? 131071 : 524287);
    if (is_set_topology_conf_overrides())
      hashCode = hashCode * 8191 + topology_conf_overrides.hashCode();

    hashCode = hashCode * 8191 + ((is_set_principal()) ? 131071 : 524287);
    if (is_set_principal())
      hashCode = hashCode * 8191 + principal.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_wait_secs()).compareTo(other.is_set_wait_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_wait_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.wait_secs, other.wait_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_num_workers()).compareTo(other.is_set_num_workers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_workers()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.num_workers, other.num_workers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_num_executors()).compareTo(other.is_set_num_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_executors()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.num_executors, other.num_executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_topology_resources_overrides()).compareTo(other.is_set_topology_resources_overrides());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_resources_overrides()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_resources_overrides, other.topology_resources_overrides);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_topology_conf_overrides()).compareTo(other.is_set_topology_conf_overrides());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_conf_overrides()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_conf_overrides, other.topology_conf_overrides);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_principal()).compareTo(other.is_set_principal());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_principal()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.principal, other.principal);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.storm.thrift.annotation.Nullable
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.storm.thrift.protocol.TProtocol iprot) throws org.apache.storm.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  public void write(org.apache.storm.thrift.protocol.TProtocol oprot) throws org.apache.storm.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("RebalanceOptions(");
    boolean first = true;

    if (is_set_wait_secs()) {
      sb.append("wait_secs:");
      sb.append(this.wait_secs);
      first = false;
    }
    if (is_set_num_workers()) {
      if (!first) sb.append(", ");
      sb.append("num_workers:");
      sb.append(this.num_workers);
      first = false;
    }
    if (is_set_num_executors()) {
      if (!first) sb.append(", ");
      sb.append("num_executors:");
      if (this.num_executors == null) {
        sb.append("null");
      } else {
        sb.append(this.num_executors);
      }
      first = false;
    }
    if (is_set_topology_resources_overrides()) {
      if (!first) sb.append(", ");
      sb.append("topology_resources_overrides:");
      if (this.topology_resources_overrides == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_resources_overrides);
      }
      first = false;
    }
    if (is_set_topology_conf_overrides()) {
      if (!first) sb.append(", ");
      sb.append("topology_conf_overrides:");
      if (this.topology_conf_overrides == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_conf_overrides);
      }
      first = false;
    }
    if (is_set_principal()) {
      if (!first) sb.append(", ");
      sb.append("principal:");
      if (this.principal == null) {
        sb.append("null");
      } else {
        sb.append(this.principal);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.storm.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.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.storm.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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.storm.thrift.protocol.TCompactProtocol(new org.apache.storm.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.storm.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class RebalanceOptionsStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public RebalanceOptionsStandardScheme getScheme() {
      return new RebalanceOptionsStandardScheme();
    }
  }

  private static class RebalanceOptionsStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<RebalanceOptions> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, RebalanceOptions struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.storm.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // WAIT_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.wait_secs = iprot.readI32();
              struct.set_wait_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // NUM_WORKERS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_workers = iprot.readI32();
              struct.set_num_workers_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // NUM_EXECUTORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map616 = iprot.readMapBegin();
                struct.num_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map616.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key617;
                int _val618;
                for (int _i619 = 0; _i619 < _map616.size; ++_i619)
                {
                  _key617 = iprot.readString();
                  _val618 = iprot.readI32();
                  struct.num_executors.put(_key617, _val618);
                }
                iprot.readMapEnd();
              }
              struct.set_num_executors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TOPOLOGY_RESOURCES_OVERRIDES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map620 = iprot.readMapBegin();
                struct.topology_resources_overrides = new java.util.HashMap<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>>(2*_map620.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key621;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> _val622;
                for (int _i623 = 0; _i623 < _map620.size; ++_i623)
                {
                  _key621 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map624 = iprot.readMapBegin();
                    _val622 = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map624.size);
                    @org.apache.storm.thrift.annotation.Nullable java.lang.String _key625;
                    double _val626;
                    for (int _i627 = 0; _i627 < _map624.size; ++_i627)
                    {
                      _key625 = iprot.readString();
                      _val626 = iprot.readDouble();
                      _val622.put(_key625, _val626);
                    }
                    iprot.readMapEnd();
                  }
                  struct.topology_resources_overrides.put(_key621, _val622);
                }
                iprot.readMapEnd();
              }
              struct.set_topology_resources_overrides_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // TOPOLOGY_CONF_OVERRIDES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_conf_overrides = iprot.readString();
              struct.set_topology_conf_overrides_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // PRINCIPAL
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.principal = iprot.readString();
              struct.set_principal_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.is_set_wait_secs()) {
        oprot.writeFieldBegin(WAIT_SECS_FIELD_DESC);
        oprot.writeI32(struct.wait_secs);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_num_workers()) {
        oprot.writeFieldBegin(NUM_WORKERS_FIELD_DESC);
        oprot.writeI32(struct.num_workers);
        oprot.writeFieldEnd();
      }
      if (struct.num_executors != null) {
        if (struct.is_set_num_executors()) {
          oprot.writeFieldBegin(NUM_EXECUTORS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.I32, struct.num_executors.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter628 : struct.num_executors.entrySet())
            {
              oprot.writeString(_iter628.getKey());
              oprot.writeI32(_iter628.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_resources_overrides != null) {
        if (struct.is_set_topology_resources_overrides()) {
          oprot.writeFieldBegin(TOPOLOGY_RESOURCES_OVERRIDES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, struct.topology_resources_overrides.size()));
            for (java.util.Map.Entry<java.lang.String, java.util.Map<java.lang.String,java.lang.Double>> _iter629 : struct.topology_resources_overrides.entrySet())
            {
              oprot.writeString(_iter629.getKey());
              {
                oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, _iter629.getValue().size()));
                for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter630 : _iter629.getValue().entrySet())
                {
                  oprot.writeString(_iter630.getKey());
                  oprot.writeDouble(_iter630.getValue());
                }
                oprot.writeMapEnd();
              }
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_conf_overrides != null) {
        if (struct.is_set_topology_conf_overrides()) {
          oprot.writeFieldBegin(TOPOLOGY_CONF_OVERRIDES_FIELD_DESC);
          oprot.writeString(struct.topology_conf_overrides);
          oprot.writeFieldEnd();
        }
      }
      if (struct.principal != null) {
        if (struct.is_set_principal()) {
          oprot.writeFieldBegin(PRINCIPAL_FIELD_DESC);
          oprot.writeString(struct.principal);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class RebalanceOptionsTupleSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public RebalanceOptionsTupleScheme getScheme() {
      return new RebalanceOptionsTupleScheme();
    }
  }

  private static class RebalanceOptionsTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<RebalanceOptions> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, RebalanceOptions struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_wait_secs()) {
        optionals.set(0);
      }
      if (struct.is_set_num_workers()) {
        optionals.set(1);
      }
      if (struct.is_set_num_executors()) {
        optionals.set(2);
      }
      if (struct.is_set_topology_resources_overrides()) {
        optionals.set(3);
      }
      if (struct.is_set_topology_conf_overrides()) {
        optionals.set(4);
      }
      if (struct.is_set_principal()) {
        optionals.set(5);
      }
      oprot.writeBitSet(optionals, 6);
      if (struct.is_set_wait_secs()) {
        oprot.writeI32(struct.wait_secs);
      }
      if (struct.is_set_num_workers()) {
        oprot.writeI32(struct.num_workers);
      }
      if (struct.is_set_num_executors()) {
        {
          oprot.writeI32(struct.num_executors.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Integer> _iter631 : struct.num_executors.entrySet())
          {
            oprot.writeString(_iter631.getKey());
            oprot.writeI32(_iter631.getValue());
          }
        }
      }
      if (struct.is_set_topology_resources_overrides()) {
        {
          oprot.writeI32(struct.topology_resources_overrides.size());
          for (java.util.Map.Entry<java.lang.String, java.util.Map<java.lang.String,java.lang.Double>> _iter632 : struct.topology_resources_overrides.entrySet())
          {
            oprot.writeString(_iter632.getKey());
            {
              oprot.writeI32(_iter632.getValue().size());
              for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter633 : _iter632.getValue().entrySet())
              {
                oprot.writeString(_iter633.getKey());
                oprot.writeDouble(_iter633.getValue());
              }
            }
          }
        }
      }
      if (struct.is_set_topology_conf_overrides()) {
        oprot.writeString(struct.topology_conf_overrides);
      }
      if (struct.is_set_principal()) {
        oprot.writeString(struct.principal);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, RebalanceOptions struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(6);
      if (incoming.get(0)) {
        struct.wait_secs = iprot.readI32();
        struct.set_wait_secs_isSet(true);
      }
      if (incoming.get(1)) {
        struct.num_workers = iprot.readI32();
        struct.set_num_workers_isSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.storm.thrift.protocol.TMap _map634 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.I32, iprot.readI32());
          struct.num_executors = new java.util.HashMap<java.lang.String,java.lang.Integer>(2*_map634.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key635;
          int _val636;
          for (int _i637 = 0; _i637 < _map634.size; ++_i637)
          {
            _key635 = iprot.readString();
            _val636 = iprot.readI32();
            struct.num_executors.put(_key635, _val636);
          }
        }
        struct.set_num_executors_isSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.storm.thrift.protocol.TMap _map638 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, iprot.readI32());
          struct.topology_resources_overrides = new java.util.HashMap<java.lang.String,java.util.Map<java.lang.String,java.lang.Double>>(2*_map638.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key639;
          @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> _val640;
          for (int _i641 = 0; _i641 < _map638.size; ++_i641)
          {
            _key639 = iprot.readString();
            {
              org.apache.storm.thrift.protocol.TMap _map642 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
              _val640 = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map642.size);
              @org.apache.storm.thrift.annotation.Nullable java.lang.String _key643;
              double _val644;
              for (int _i645 = 0; _i645 < _map642.size; ++_i645)
              {
                _key643 = iprot.readString();
                _val644 = iprot.readDouble();
                _val640.put(_key643, _val644);
              }
            }
            struct.topology_resources_overrides.put(_key639, _val640);
          }
        }
        struct.set_topology_resources_overrides_isSet(true);
      }
      if (incoming.get(4)) {
        struct.topology_conf_overrides = iprot.readString();
        struct.set_topology_conf_overrides_isSet(true);
      }
      if (incoming.get(5)) {
        struct.principal = iprot.readString();
        struct.set_principal_isSet(true);
      }
    }
  }

  private static <S extends org.apache.storm.thrift.scheme.IScheme> S scheme(org.apache.storm.thrift.protocol.TProtocol proto) {
    return (org.apache.storm.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

