/**
 * 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.12.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.12.0)")
public class SupervisorSummary implements org.apache.storm.thrift.TBase<SupervisorSummary, SupervisorSummary._Fields>, java.io.Serializable, Cloneable, Comparable<SupervisorSummary> {
  private static final org.apache.storm.thrift.protocol.TStruct STRUCT_DESC = new org.apache.storm.thrift.protocol.TStruct("SupervisorSummary");

  private static final org.apache.storm.thrift.protocol.TField HOST_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("host", org.apache.storm.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.storm.thrift.protocol.TField UPTIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("uptime_secs", org.apache.storm.thrift.protocol.TType.I32, (short)2);
  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)3);
  private static final org.apache.storm.thrift.protocol.TField NUM_USED_WORKERS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("num_used_workers", org.apache.storm.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.storm.thrift.protocol.TField SUPERVISOR_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("supervisor_id", org.apache.storm.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.storm.thrift.protocol.TField VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("version", org.apache.storm.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.storm.thrift.protocol.TField TOTAL_RESOURCES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("total_resources", org.apache.storm.thrift.protocol.TType.MAP, (short)7);
  private static final org.apache.storm.thrift.protocol.TField USED_MEM_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("used_mem", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)8);
  private static final org.apache.storm.thrift.protocol.TField USED_CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("used_cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)9);
  private static final org.apache.storm.thrift.protocol.TField FRAGMENTED_MEM_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("fragmented_mem", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)10);
  private static final org.apache.storm.thrift.protocol.TField FRAGMENTED_CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("fragmented_cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)11);
  private static final org.apache.storm.thrift.protocol.TField BLACKLISTED_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("blacklisted", org.apache.storm.thrift.protocol.TType.BOOL, (short)12);
  private static final org.apache.storm.thrift.protocol.TField USED_GENERIC_RESOURCES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("used_generic_resources", org.apache.storm.thrift.protocol.TType.MAP, (short)13);

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String host; // required
  private int uptime_secs; // required
  private int num_workers; // required
  private int num_used_workers; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String supervisor_id; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> total_resources; // optional
  private double used_mem; // optional
  private double used_cpu; // optional
  private double fragmented_mem; // optional
  private double fragmented_cpu; // optional
  private boolean blacklisted; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> used_generic_resources; // 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 {
    HOST((short)1, "host"),
    UPTIME_SECS((short)2, "uptime_secs"),
    NUM_WORKERS((short)3, "num_workers"),
    NUM_USED_WORKERS((short)4, "num_used_workers"),
    SUPERVISOR_ID((short)5, "supervisor_id"),
    VERSION((short)6, "version"),
    TOTAL_RESOURCES((short)7, "total_resources"),
    USED_MEM((short)8, "used_mem"),
    USED_CPU((short)9, "used_cpu"),
    FRAGMENTED_MEM((short)10, "fragmented_mem"),
    FRAGMENTED_CPU((short)11, "fragmented_cpu"),
    BLACKLISTED((short)12, "blacklisted"),
    USED_GENERIC_RESOURCES((short)13, "used_generic_resources");

    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: // HOST
          return HOST;
        case 2: // UPTIME_SECS
          return UPTIME_SECS;
        case 3: // NUM_WORKERS
          return NUM_WORKERS;
        case 4: // NUM_USED_WORKERS
          return NUM_USED_WORKERS;
        case 5: // SUPERVISOR_ID
          return SUPERVISOR_ID;
        case 6: // VERSION
          return VERSION;
        case 7: // TOTAL_RESOURCES
          return TOTAL_RESOURCES;
        case 8: // USED_MEM
          return USED_MEM;
        case 9: // USED_CPU
          return USED_CPU;
        case 10: // FRAGMENTED_MEM
          return FRAGMENTED_MEM;
        case 11: // FRAGMENTED_CPU
          return FRAGMENTED_CPU;
        case 12: // BLACKLISTED
          return BLACKLISTED;
        case 13: // USED_GENERIC_RESOURCES
          return USED_GENERIC_RESOURCES;
        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 __UPTIME_SECS_ISSET_ID = 0;
  private static final int __NUM_WORKERS_ISSET_ID = 1;
  private static final int __NUM_USED_WORKERS_ISSET_ID = 2;
  private static final int __USED_MEM_ISSET_ID = 3;
  private static final int __USED_CPU_ISSET_ID = 4;
  private static final int __FRAGMENTED_MEM_ISSET_ID = 5;
  private static final int __FRAGMENTED_CPU_ISSET_ID = 6;
  private static final int __BLACKLISTED_ISSET_ID = 7;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.VERSION,_Fields.TOTAL_RESOURCES,_Fields.USED_MEM,_Fields.USED_CPU,_Fields.FRAGMENTED_MEM,_Fields.FRAGMENTED_CPU,_Fields.BLACKLISTED,_Fields.USED_GENERIC_RESOURCES};
  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.HOST, new org.apache.storm.thrift.meta_data.FieldMetaData("host", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.UPTIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("uptime_secs", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NUM_USED_WORKERS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_used_workers", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.SUPERVISOR_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("supervisor_id", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("version", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOTAL_RESOURCES, new org.apache.storm.thrift.meta_data.FieldMetaData("total_resources", 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.DOUBLE))));
    tmpMap.put(_Fields.USED_MEM, new org.apache.storm.thrift.meta_data.FieldMetaData("used_mem", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.USED_CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("used_cpu", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.FRAGMENTED_MEM, new org.apache.storm.thrift.meta_data.FieldMetaData("fragmented_mem", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.FRAGMENTED_CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("fragmented_cpu", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.BLACKLISTED, new org.apache.storm.thrift.meta_data.FieldMetaData("blacklisted", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.BOOL)));
    tmpMap.put(_Fields.USED_GENERIC_RESOURCES, new org.apache.storm.thrift.meta_data.FieldMetaData("used_generic_resources", 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.DOUBLE))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SupervisorSummary.class, metaDataMap);
  }

  public SupervisorSummary() {
    this.version = "VERSION_NOT_PROVIDED";

  }

  public SupervisorSummary(
    java.lang.String host,
    int uptime_secs,
    int num_workers,
    int num_used_workers,
    java.lang.String supervisor_id)
  {
    this();
    this.host = host;
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
    this.num_used_workers = num_used_workers;
    set_num_used_workers_isSet(true);
    this.supervisor_id = supervisor_id;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public SupervisorSummary(SupervisorSummary other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_host()) {
      this.host = other.host;
    }
    this.uptime_secs = other.uptime_secs;
    this.num_workers = other.num_workers;
    this.num_used_workers = other.num_used_workers;
    if (other.is_set_supervisor_id()) {
      this.supervisor_id = other.supervisor_id;
    }
    if (other.is_set_version()) {
      this.version = other.version;
    }
    if (other.is_set_total_resources()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__total_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(other.total_resources);
      this.total_resources = __this__total_resources;
    }
    this.used_mem = other.used_mem;
    this.used_cpu = other.used_cpu;
    this.fragmented_mem = other.fragmented_mem;
    this.fragmented_cpu = other.fragmented_cpu;
    this.blacklisted = other.blacklisted;
    if (other.is_set_used_generic_resources()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__used_generic_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(other.used_generic_resources);
      this.used_generic_resources = __this__used_generic_resources;
    }
  }

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

  @Override
  public void clear() {
    this.host = null;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    set_num_workers_isSet(false);
    this.num_workers = 0;
    set_num_used_workers_isSet(false);
    this.num_used_workers = 0;
    this.supervisor_id = null;
    this.version = "VERSION_NOT_PROVIDED";

    this.total_resources = null;
    set_used_mem_isSet(false);
    this.used_mem = 0.0;
    set_used_cpu_isSet(false);
    this.used_cpu = 0.0;
    set_fragmented_mem_isSet(false);
    this.fragmented_mem = 0.0;
    set_fragmented_cpu_isSet(false);
    this.fragmented_cpu = 0.0;
    set_blacklisted_isSet(false);
    this.blacklisted = false;
    this.used_generic_resources = null;
  }

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

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

  public void unset_host() {
    this.host = null;
  }

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

  public void set_host_isSet(boolean value) {
    if (!value) {
      this.host = null;
    }
  }

  public int get_uptime_secs() {
    return this.uptime_secs;
  }

  public void set_uptime_secs(int uptime_secs) {
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
  }

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

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

  public void set_uptime_secs_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __UPTIME_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_used_workers() {
    return this.num_used_workers;
  }

  public void set_num_used_workers(int num_used_workers) {
    this.num_used_workers = num_used_workers;
    set_num_used_workers_isSet(true);
  }

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

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

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

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

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

  public void unset_supervisor_id() {
    this.supervisor_id = null;
  }

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

  public void set_supervisor_id_isSet(boolean value) {
    if (!value) {
      this.supervisor_id = null;
    }
  }

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

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

  public void unset_version() {
    this.version = null;
  }

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

  public void set_version_isSet(boolean value) {
    if (!value) {
      this.version = null;
    }
  }

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

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

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

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

  public void unset_total_resources() {
    this.total_resources = null;
  }

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

  public void set_total_resources_isSet(boolean value) {
    if (!value) {
      this.total_resources = null;
    }
  }

  public double get_used_mem() {
    return this.used_mem;
  }

  public void set_used_mem(double used_mem) {
    this.used_mem = used_mem;
    set_used_mem_isSet(true);
  }

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

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

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

  public double get_used_cpu() {
    return this.used_cpu;
  }

  public void set_used_cpu(double used_cpu) {
    this.used_cpu = used_cpu;
    set_used_cpu_isSet(true);
  }

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

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

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

  public double get_fragmented_mem() {
    return this.fragmented_mem;
  }

  public void set_fragmented_mem(double fragmented_mem) {
    this.fragmented_mem = fragmented_mem;
    set_fragmented_mem_isSet(true);
  }

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

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

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

  public double get_fragmented_cpu() {
    return this.fragmented_cpu;
  }

  public void set_fragmented_cpu(double fragmented_cpu) {
    this.fragmented_cpu = fragmented_cpu;
    set_fragmented_cpu_isSet(true);
  }

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

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

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

  public boolean is_blacklisted() {
    return this.blacklisted;
  }

  public void set_blacklisted(boolean blacklisted) {
    this.blacklisted = blacklisted;
    set_blacklisted_isSet(true);
  }

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

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

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

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

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

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

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

  public void unset_used_generic_resources() {
    this.used_generic_resources = null;
  }

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

  public void set_used_generic_resources_isSet(boolean value) {
    if (!value) {
      this.used_generic_resources = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case HOST:
      if (value == null) {
        unset_host();
      } else {
        set_host((java.lang.String)value);
      }
      break;

    case UPTIME_SECS:
      if (value == null) {
        unset_uptime_secs();
      } else {
        set_uptime_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_USED_WORKERS:
      if (value == null) {
        unset_num_used_workers();
      } else {
        set_num_used_workers((java.lang.Integer)value);
      }
      break;

    case SUPERVISOR_ID:
      if (value == null) {
        unset_supervisor_id();
      } else {
        set_supervisor_id((java.lang.String)value);
      }
      break;

    case VERSION:
      if (value == null) {
        unset_version();
      } else {
        set_version((java.lang.String)value);
      }
      break;

    case TOTAL_RESOURCES:
      if (value == null) {
        unset_total_resources();
      } else {
        set_total_resources((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

    case USED_MEM:
      if (value == null) {
        unset_used_mem();
      } else {
        set_used_mem((java.lang.Double)value);
      }
      break;

    case USED_CPU:
      if (value == null) {
        unset_used_cpu();
      } else {
        set_used_cpu((java.lang.Double)value);
      }
      break;

    case FRAGMENTED_MEM:
      if (value == null) {
        unset_fragmented_mem();
      } else {
        set_fragmented_mem((java.lang.Double)value);
      }
      break;

    case FRAGMENTED_CPU:
      if (value == null) {
        unset_fragmented_cpu();
      } else {
        set_fragmented_cpu((java.lang.Double)value);
      }
      break;

    case BLACKLISTED:
      if (value == null) {
        unset_blacklisted();
      } else {
        set_blacklisted((java.lang.Boolean)value);
      }
      break;

    case USED_GENERIC_RESOURCES:
      if (value == null) {
        unset_used_generic_resources();
      } else {
        set_used_generic_resources((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

    }
  }

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

    case UPTIME_SECS:
      return get_uptime_secs();

    case NUM_WORKERS:
      return get_num_workers();

    case NUM_USED_WORKERS:
      return get_num_used_workers();

    case SUPERVISOR_ID:
      return get_supervisor_id();

    case VERSION:
      return get_version();

    case TOTAL_RESOURCES:
      return get_total_resources();

    case USED_MEM:
      return get_used_mem();

    case USED_CPU:
      return get_used_cpu();

    case FRAGMENTED_MEM:
      return get_fragmented_mem();

    case FRAGMENTED_CPU:
      return get_fragmented_cpu();

    case BLACKLISTED:
      return is_blacklisted();

    case USED_GENERIC_RESOURCES:
      return get_used_generic_resources();

    }
    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 HOST:
      return is_set_host();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case NUM_WORKERS:
      return is_set_num_workers();
    case NUM_USED_WORKERS:
      return is_set_num_used_workers();
    case SUPERVISOR_ID:
      return is_set_supervisor_id();
    case VERSION:
      return is_set_version();
    case TOTAL_RESOURCES:
      return is_set_total_resources();
    case USED_MEM:
      return is_set_used_mem();
    case USED_CPU:
      return is_set_used_cpu();
    case FRAGMENTED_MEM:
      return is_set_fragmented_mem();
    case FRAGMENTED_CPU:
      return is_set_fragmented_cpu();
    case BLACKLISTED:
      return is_set_blacklisted();
    case USED_GENERIC_RESOURCES:
      return is_set_used_generic_resources();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_host = true && this.is_set_host();
    boolean that_present_host = true && that.is_set_host();
    if (this_present_host || that_present_host) {
      if (!(this_present_host && that_present_host))
        return false;
      if (!this.host.equals(that.host))
        return false;
    }

    boolean this_present_uptime_secs = true;
    boolean that_present_uptime_secs = true;
    if (this_present_uptime_secs || that_present_uptime_secs) {
      if (!(this_present_uptime_secs && that_present_uptime_secs))
        return false;
      if (this.uptime_secs != that.uptime_secs)
        return false;
    }

    boolean this_present_num_workers = true;
    boolean that_present_num_workers = true;
    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_used_workers = true;
    boolean that_present_num_used_workers = true;
    if (this_present_num_used_workers || that_present_num_used_workers) {
      if (!(this_present_num_used_workers && that_present_num_used_workers))
        return false;
      if (this.num_used_workers != that.num_used_workers)
        return false;
    }

    boolean this_present_supervisor_id = true && this.is_set_supervisor_id();
    boolean that_present_supervisor_id = true && that.is_set_supervisor_id();
    if (this_present_supervisor_id || that_present_supervisor_id) {
      if (!(this_present_supervisor_id && that_present_supervisor_id))
        return false;
      if (!this.supervisor_id.equals(that.supervisor_id))
        return false;
    }

    boolean this_present_version = true && this.is_set_version();
    boolean that_present_version = true && that.is_set_version();
    if (this_present_version || that_present_version) {
      if (!(this_present_version && that_present_version))
        return false;
      if (!this.version.equals(that.version))
        return false;
    }

    boolean this_present_total_resources = true && this.is_set_total_resources();
    boolean that_present_total_resources = true && that.is_set_total_resources();
    if (this_present_total_resources || that_present_total_resources) {
      if (!(this_present_total_resources && that_present_total_resources))
        return false;
      if (!this.total_resources.equals(that.total_resources))
        return false;
    }

    boolean this_present_used_mem = true && this.is_set_used_mem();
    boolean that_present_used_mem = true && that.is_set_used_mem();
    if (this_present_used_mem || that_present_used_mem) {
      if (!(this_present_used_mem && that_present_used_mem))
        return false;
      if (this.used_mem != that.used_mem)
        return false;
    }

    boolean this_present_used_cpu = true && this.is_set_used_cpu();
    boolean that_present_used_cpu = true && that.is_set_used_cpu();
    if (this_present_used_cpu || that_present_used_cpu) {
      if (!(this_present_used_cpu && that_present_used_cpu))
        return false;
      if (this.used_cpu != that.used_cpu)
        return false;
    }

    boolean this_present_fragmented_mem = true && this.is_set_fragmented_mem();
    boolean that_present_fragmented_mem = true && that.is_set_fragmented_mem();
    if (this_present_fragmented_mem || that_present_fragmented_mem) {
      if (!(this_present_fragmented_mem && that_present_fragmented_mem))
        return false;
      if (this.fragmented_mem != that.fragmented_mem)
        return false;
    }

    boolean this_present_fragmented_cpu = true && this.is_set_fragmented_cpu();
    boolean that_present_fragmented_cpu = true && that.is_set_fragmented_cpu();
    if (this_present_fragmented_cpu || that_present_fragmented_cpu) {
      if (!(this_present_fragmented_cpu && that_present_fragmented_cpu))
        return false;
      if (this.fragmented_cpu != that.fragmented_cpu)
        return false;
    }

    boolean this_present_blacklisted = true && this.is_set_blacklisted();
    boolean that_present_blacklisted = true && that.is_set_blacklisted();
    if (this_present_blacklisted || that_present_blacklisted) {
      if (!(this_present_blacklisted && that_present_blacklisted))
        return false;
      if (this.blacklisted != that.blacklisted)
        return false;
    }

    boolean this_present_used_generic_resources = true && this.is_set_used_generic_resources();
    boolean that_present_used_generic_resources = true && that.is_set_used_generic_resources();
    if (this_present_used_generic_resources || that_present_used_generic_resources) {
      if (!(this_present_used_generic_resources && that_present_used_generic_resources))
        return false;
      if (!this.used_generic_resources.equals(that.used_generic_resources))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_host()) ? 131071 : 524287);
    if (is_set_host())
      hashCode = hashCode * 8191 + host.hashCode();

    hashCode = hashCode * 8191 + uptime_secs;

    hashCode = hashCode * 8191 + num_workers;

    hashCode = hashCode * 8191 + num_used_workers;

    hashCode = hashCode * 8191 + ((is_set_supervisor_id()) ? 131071 : 524287);
    if (is_set_supervisor_id())
      hashCode = hashCode * 8191 + supervisor_id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_version()) ? 131071 : 524287);
    if (is_set_version())
      hashCode = hashCode * 8191 + version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_total_resources()) ? 131071 : 524287);
    if (is_set_total_resources())
      hashCode = hashCode * 8191 + total_resources.hashCode();

    hashCode = hashCode * 8191 + ((is_set_used_mem()) ? 131071 : 524287);
    if (is_set_used_mem())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(used_mem);

    hashCode = hashCode * 8191 + ((is_set_used_cpu()) ? 131071 : 524287);
    if (is_set_used_cpu())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(used_cpu);

    hashCode = hashCode * 8191 + ((is_set_fragmented_mem()) ? 131071 : 524287);
    if (is_set_fragmented_mem())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(fragmented_mem);

    hashCode = hashCode * 8191 + ((is_set_fragmented_cpu()) ? 131071 : 524287);
    if (is_set_fragmented_cpu())
      hashCode = hashCode * 8191 + org.apache.storm.thrift.TBaseHelper.hashCode(fragmented_cpu);

    hashCode = hashCode * 8191 + ((is_set_blacklisted()) ? 131071 : 524287);
    if (is_set_blacklisted())
      hashCode = hashCode * 8191 + ((blacklisted) ? 131071 : 524287);

    hashCode = hashCode * 8191 + ((is_set_used_generic_resources()) ? 131071 : 524287);
    if (is_set_used_generic_resources())
      hashCode = hashCode * 8191 + used_generic_resources.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_host()).compareTo(other.is_set_host());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_host()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.host, other.host);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_uptime_secs()).compareTo(other.is_set_uptime_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_uptime_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.uptime_secs, other.uptime_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_used_workers()).compareTo(other.is_set_num_used_workers());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_used_workers()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.num_used_workers, other.num_used_workers);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_supervisor_id()).compareTo(other.is_set_supervisor_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_supervisor_id()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.supervisor_id, other.supervisor_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_version()).compareTo(other.is_set_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.version, other.version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_total_resources()).compareTo(other.is_set_total_resources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_total_resources()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.total_resources, other.total_resources);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_used_mem()).compareTo(other.is_set_used_mem());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_used_mem()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.used_mem, other.used_mem);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_used_cpu()).compareTo(other.is_set_used_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_used_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.used_cpu, other.used_cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_fragmented_mem()).compareTo(other.is_set_fragmented_mem());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_fragmented_mem()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.fragmented_mem, other.fragmented_mem);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_fragmented_cpu()).compareTo(other.is_set_fragmented_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_fragmented_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.fragmented_cpu, other.fragmented_cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_blacklisted()).compareTo(other.is_set_blacklisted());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_blacklisted()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.blacklisted, other.blacklisted);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_used_generic_resources()).compareTo(other.is_set_used_generic_resources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_used_generic_resources()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.used_generic_resources, other.used_generic_resources);
      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("SupervisorSummary(");
    boolean first = true;

    sb.append("host:");
    if (this.host == null) {
      sb.append("null");
    } else {
      sb.append(this.host);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("uptime_secs:");
    sb.append(this.uptime_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("num_workers:");
    sb.append(this.num_workers);
    first = false;
    if (!first) sb.append(", ");
    sb.append("num_used_workers:");
    sb.append(this.num_used_workers);
    first = false;
    if (!first) sb.append(", ");
    sb.append("supervisor_id:");
    if (this.supervisor_id == null) {
      sb.append("null");
    } else {
      sb.append(this.supervisor_id);
    }
    first = false;
    if (is_set_version()) {
      if (!first) sb.append(", ");
      sb.append("version:");
      if (this.version == null) {
        sb.append("null");
      } else {
        sb.append(this.version);
      }
      first = false;
    }
    if (is_set_total_resources()) {
      if (!first) sb.append(", ");
      sb.append("total_resources:");
      if (this.total_resources == null) {
        sb.append("null");
      } else {
        sb.append(this.total_resources);
      }
      first = false;
    }
    if (is_set_used_mem()) {
      if (!first) sb.append(", ");
      sb.append("used_mem:");
      sb.append(this.used_mem);
      first = false;
    }
    if (is_set_used_cpu()) {
      if (!first) sb.append(", ");
      sb.append("used_cpu:");
      sb.append(this.used_cpu);
      first = false;
    }
    if (is_set_fragmented_mem()) {
      if (!first) sb.append(", ");
      sb.append("fragmented_mem:");
      sb.append(this.fragmented_mem);
      first = false;
    }
    if (is_set_fragmented_cpu()) {
      if (!first) sb.append(", ");
      sb.append("fragmented_cpu:");
      sb.append(this.fragmented_cpu);
      first = false;
    }
    if (is_set_blacklisted()) {
      if (!first) sb.append(", ");
      sb.append("blacklisted:");
      sb.append(this.blacklisted);
      first = false;
    }
    if (is_set_used_generic_resources()) {
      if (!first) sb.append(", ");
      sb.append("used_generic_resources:");
      if (this.used_generic_resources == null) {
        sb.append("null");
      } else {
        sb.append(this.used_generic_resources);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.storm.thrift.TException {
    // check for required fields
    if (!is_set_host()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'host' is unset! Struct:" + toString());
    }

    if (!is_set_uptime_secs()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'uptime_secs' is unset! Struct:" + toString());
    }

    if (!is_set_num_workers()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'num_workers' is unset! Struct:" + toString());
    }

    if (!is_set_num_used_workers()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'num_used_workers' is unset! Struct:" + toString());
    }

    if (!is_set_supervisor_id()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'supervisor_id' is unset! Struct:" + toString());
    }

    // 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 SupervisorSummaryStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public SupervisorSummaryStandardScheme getScheme() {
      return new SupervisorSummaryStandardScheme();
    }
  }

  private static class SupervisorSummaryStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<SupervisorSummary> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, SupervisorSummary 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: // HOST
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.host = iprot.readString();
              struct.set_host_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // UPTIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.uptime_secs = iprot.readI32();
              struct.set_uptime_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // 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 4: // NUM_USED_WORKERS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_used_workers = iprot.readI32();
              struct.set_num_used_workers_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // SUPERVISOR_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.supervisor_id = iprot.readString();
              struct.set_supervisor_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.version = iprot.readString();
              struct.set_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // TOTAL_RESOURCES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map146 = iprot.readMapBegin();
                struct.total_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map146.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key147;
                double _val148;
                for (int _i149 = 0; _i149 < _map146.size; ++_i149)
                {
                  _key147 = iprot.readString();
                  _val148 = iprot.readDouble();
                  struct.total_resources.put(_key147, _val148);
                }
                iprot.readMapEnd();
              }
              struct.set_total_resources_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // USED_MEM
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.used_mem = iprot.readDouble();
              struct.set_used_mem_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // USED_CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.used_cpu = iprot.readDouble();
              struct.set_used_cpu_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 10: // FRAGMENTED_MEM
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.fragmented_mem = iprot.readDouble();
              struct.set_fragmented_mem_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // FRAGMENTED_CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.fragmented_cpu = iprot.readDouble();
              struct.set_fragmented_cpu_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // BLACKLISTED
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.BOOL) {
              struct.blacklisted = iprot.readBool();
              struct.set_blacklisted_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 13: // USED_GENERIC_RESOURCES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map150 = iprot.readMapBegin();
                struct.used_generic_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map150.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key151;
                double _val152;
                for (int _i153 = 0; _i153 < _map150.size; ++_i153)
                {
                  _key151 = iprot.readString();
                  _val152 = iprot.readDouble();
                  struct.used_generic_resources.put(_key151, _val152);
                }
                iprot.readMapEnd();
              }
              struct.set_used_generic_resources_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, SupervisorSummary struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.host != null) {
        oprot.writeFieldBegin(HOST_FIELD_DESC);
        oprot.writeString(struct.host);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
      oprot.writeI32(struct.uptime_secs);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(NUM_WORKERS_FIELD_DESC);
      oprot.writeI32(struct.num_workers);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(NUM_USED_WORKERS_FIELD_DESC);
      oprot.writeI32(struct.num_used_workers);
      oprot.writeFieldEnd();
      if (struct.supervisor_id != null) {
        oprot.writeFieldBegin(SUPERVISOR_ID_FIELD_DESC);
        oprot.writeString(struct.supervisor_id);
        oprot.writeFieldEnd();
      }
      if (struct.version != null) {
        if (struct.is_set_version()) {
          oprot.writeFieldBegin(VERSION_FIELD_DESC);
          oprot.writeString(struct.version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.total_resources != null) {
        if (struct.is_set_total_resources()) {
          oprot.writeFieldBegin(TOTAL_RESOURCES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.total_resources.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter154 : struct.total_resources.entrySet())
            {
              oprot.writeString(_iter154.getKey());
              oprot.writeDouble(_iter154.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_used_mem()) {
        oprot.writeFieldBegin(USED_MEM_FIELD_DESC);
        oprot.writeDouble(struct.used_mem);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_used_cpu()) {
        oprot.writeFieldBegin(USED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.used_cpu);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_fragmented_mem()) {
        oprot.writeFieldBegin(FRAGMENTED_MEM_FIELD_DESC);
        oprot.writeDouble(struct.fragmented_mem);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_fragmented_cpu()) {
        oprot.writeFieldBegin(FRAGMENTED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.fragmented_cpu);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_blacklisted()) {
        oprot.writeFieldBegin(BLACKLISTED_FIELD_DESC);
        oprot.writeBool(struct.blacklisted);
        oprot.writeFieldEnd();
      }
      if (struct.used_generic_resources != null) {
        if (struct.is_set_used_generic_resources()) {
          oprot.writeFieldBegin(USED_GENERIC_RESOURCES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.used_generic_resources.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter155 : struct.used_generic_resources.entrySet())
            {
              oprot.writeString(_iter155.getKey());
              oprot.writeDouble(_iter155.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class SupervisorSummaryTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<SupervisorSummary> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, SupervisorSummary struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.host);
      oprot.writeI32(struct.uptime_secs);
      oprot.writeI32(struct.num_workers);
      oprot.writeI32(struct.num_used_workers);
      oprot.writeString(struct.supervisor_id);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_version()) {
        optionals.set(0);
      }
      if (struct.is_set_total_resources()) {
        optionals.set(1);
      }
      if (struct.is_set_used_mem()) {
        optionals.set(2);
      }
      if (struct.is_set_used_cpu()) {
        optionals.set(3);
      }
      if (struct.is_set_fragmented_mem()) {
        optionals.set(4);
      }
      if (struct.is_set_fragmented_cpu()) {
        optionals.set(5);
      }
      if (struct.is_set_blacklisted()) {
        optionals.set(6);
      }
      if (struct.is_set_used_generic_resources()) {
        optionals.set(7);
      }
      oprot.writeBitSet(optionals, 8);
      if (struct.is_set_version()) {
        oprot.writeString(struct.version);
      }
      if (struct.is_set_total_resources()) {
        {
          oprot.writeI32(struct.total_resources.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter156 : struct.total_resources.entrySet())
          {
            oprot.writeString(_iter156.getKey());
            oprot.writeDouble(_iter156.getValue());
          }
        }
      }
      if (struct.is_set_used_mem()) {
        oprot.writeDouble(struct.used_mem);
      }
      if (struct.is_set_used_cpu()) {
        oprot.writeDouble(struct.used_cpu);
      }
      if (struct.is_set_fragmented_mem()) {
        oprot.writeDouble(struct.fragmented_mem);
      }
      if (struct.is_set_fragmented_cpu()) {
        oprot.writeDouble(struct.fragmented_cpu);
      }
      if (struct.is_set_blacklisted()) {
        oprot.writeBool(struct.blacklisted);
      }
      if (struct.is_set_used_generic_resources()) {
        {
          oprot.writeI32(struct.used_generic_resources.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter157 : struct.used_generic_resources.entrySet())
          {
            oprot.writeString(_iter157.getKey());
            oprot.writeDouble(_iter157.getValue());
          }
        }
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, SupervisorSummary struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.host = iprot.readString();
      struct.set_host_isSet(true);
      struct.uptime_secs = iprot.readI32();
      struct.set_uptime_secs_isSet(true);
      struct.num_workers = iprot.readI32();
      struct.set_num_workers_isSet(true);
      struct.num_used_workers = iprot.readI32();
      struct.set_num_used_workers_isSet(true);
      struct.supervisor_id = iprot.readString();
      struct.set_supervisor_id_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(8);
      if (incoming.get(0)) {
        struct.version = iprot.readString();
        struct.set_version_isSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.storm.thrift.protocol.TMap _map158 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.total_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map158.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key159;
          double _val160;
          for (int _i161 = 0; _i161 < _map158.size; ++_i161)
          {
            _key159 = iprot.readString();
            _val160 = iprot.readDouble();
            struct.total_resources.put(_key159, _val160);
          }
        }
        struct.set_total_resources_isSet(true);
      }
      if (incoming.get(2)) {
        struct.used_mem = iprot.readDouble();
        struct.set_used_mem_isSet(true);
      }
      if (incoming.get(3)) {
        struct.used_cpu = iprot.readDouble();
        struct.set_used_cpu_isSet(true);
      }
      if (incoming.get(4)) {
        struct.fragmented_mem = iprot.readDouble();
        struct.set_fragmented_mem_isSet(true);
      }
      if (incoming.get(5)) {
        struct.fragmented_cpu = iprot.readDouble();
        struct.set_fragmented_cpu_isSet(true);
      }
      if (incoming.get(6)) {
        struct.blacklisted = iprot.readBool();
        struct.set_blacklisted_isSet(true);
      }
      if (incoming.get(7)) {
        {
          org.apache.storm.thrift.protocol.TMap _map162 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.used_generic_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map162.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key163;
          double _val164;
          for (int _i165 = 0; _i165 < _map162.size; ++_i165)
          {
            _key163 = iprot.readString();
            _val164 = iprot.readDouble();
            struct.used_generic_resources.put(_key163, _val164);
          }
        }
        struct.set_used_generic_resources_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();
  }
}

