/**
 * 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.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

  /** 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");

    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;
        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};
  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)));
    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;
  }

  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;
  }

  @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 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;

    }
  }

  @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();

    }
    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();
    }
    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;
    }

    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);

    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;
      }
    }
    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;
    }
    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 _map126 = iprot.readMapBegin();
                struct.total_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map126.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key127;
                double _val128;
                for (int _i129 = 0; _i129 < _map126.size; ++_i129)
                {
                  _key127 = iprot.readString();
                  _val128 = iprot.readDouble();
                  struct.total_resources.put(_key127, _val128);
                }
                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;
          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> _iter130 : struct.total_resources.entrySet())
            {
              oprot.writeString(_iter130.getKey());
              oprot.writeDouble(_iter130.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();
      }
      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);
      }
      oprot.writeBitSet(optionals, 7);
      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> _iter131 : struct.total_resources.entrySet())
          {
            oprot.writeString(_iter131.getKey());
            oprot.writeDouble(_iter131.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);
      }
    }

    @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(7);
      if (incoming.get(0)) {
        struct.version = iprot.readString();
        struct.set_version_isSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.storm.thrift.protocol.TMap _map132 = 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*_map132.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key133;
          double _val134;
          for (int _i135 = 0; _i135 < _map132.size; ++_i135)
          {
            _key133 = iprot.readString();
            _val134 = iprot.readDouble();
            struct.total_resources.put(_key133, _val134);
          }
        }
        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);
      }
    }
  }

  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();
  }
}

