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

  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)1);
  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)2);
  private static final org.apache.storm.thrift.protocol.TField PORT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("port", org.apache.storm.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_id", org.apache.storm.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_NAME_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_name", org.apache.storm.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.storm.thrift.protocol.TField NUM_EXECUTORS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("num_executors", org.apache.storm.thrift.protocol.TType.I32, (short)6);
  private static final org.apache.storm.thrift.protocol.TField COMPONENT_TO_NUM_TASKS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("component_to_num_tasks", org.apache.storm.thrift.protocol.TType.MAP, (short)7);
  private static final org.apache.storm.thrift.protocol.TField TIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("time_secs", org.apache.storm.thrift.protocol.TType.I32, (short)8);
  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)9);
  private static final org.apache.storm.thrift.protocol.TField REQUESTED_MEMONHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("requested_memonheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)521);
  private static final org.apache.storm.thrift.protocol.TField REQUESTED_MEMOFFHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("requested_memoffheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)522);
  private static final org.apache.storm.thrift.protocol.TField REQUESTED_CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("requested_cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)523);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNED_MEMONHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assigned_memonheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)524);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNED_MEMOFFHEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assigned_memoffheap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)525);
  private static final org.apache.storm.thrift.protocol.TField ASSIGNED_CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("assigned_cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)526);
  private static final org.apache.storm.thrift.protocol.TField OWNER_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("owner", org.apache.storm.thrift.protocol.TType.STRING, (short)527);

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String supervisor_id; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String host; // optional
  private int port; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_id; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_name; // optional
  private int num_executors; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Long> component_to_num_tasks; // optional
  private int time_secs; // optional
  private int uptime_secs; // optional
  private double requested_memonheap; // optional
  private double requested_memoffheap; // optional
  private double requested_cpu; // optional
  private double assigned_memonheap; // optional
  private double assigned_memoffheap; // optional
  private double assigned_cpu; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String owner; // 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 {
    SUPERVISOR_ID((short)1, "supervisor_id"),
    HOST((short)2, "host"),
    PORT((short)3, "port"),
    TOPOLOGY_ID((short)4, "topology_id"),
    TOPOLOGY_NAME((short)5, "topology_name"),
    NUM_EXECUTORS((short)6, "num_executors"),
    COMPONENT_TO_NUM_TASKS((short)7, "component_to_num_tasks"),
    TIME_SECS((short)8, "time_secs"),
    UPTIME_SECS((short)9, "uptime_secs"),
    REQUESTED_MEMONHEAP((short)521, "requested_memonheap"),
    REQUESTED_MEMOFFHEAP((short)522, "requested_memoffheap"),
    REQUESTED_CPU((short)523, "requested_cpu"),
    ASSIGNED_MEMONHEAP((short)524, "assigned_memonheap"),
    ASSIGNED_MEMOFFHEAP((short)525, "assigned_memoffheap"),
    ASSIGNED_CPU((short)526, "assigned_cpu"),
    OWNER((short)527, "owner");

    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: // SUPERVISOR_ID
          return SUPERVISOR_ID;
        case 2: // HOST
          return HOST;
        case 3: // PORT
          return PORT;
        case 4: // TOPOLOGY_ID
          return TOPOLOGY_ID;
        case 5: // TOPOLOGY_NAME
          return TOPOLOGY_NAME;
        case 6: // NUM_EXECUTORS
          return NUM_EXECUTORS;
        case 7: // COMPONENT_TO_NUM_TASKS
          return COMPONENT_TO_NUM_TASKS;
        case 8: // TIME_SECS
          return TIME_SECS;
        case 9: // UPTIME_SECS
          return UPTIME_SECS;
        case 521: // REQUESTED_MEMONHEAP
          return REQUESTED_MEMONHEAP;
        case 522: // REQUESTED_MEMOFFHEAP
          return REQUESTED_MEMOFFHEAP;
        case 523: // REQUESTED_CPU
          return REQUESTED_CPU;
        case 524: // ASSIGNED_MEMONHEAP
          return ASSIGNED_MEMONHEAP;
        case 525: // ASSIGNED_MEMOFFHEAP
          return ASSIGNED_MEMOFFHEAP;
        case 526: // ASSIGNED_CPU
          return ASSIGNED_CPU;
        case 527: // OWNER
          return OWNER;
        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 __PORT_ISSET_ID = 0;
  private static final int __NUM_EXECUTORS_ISSET_ID = 1;
  private static final int __TIME_SECS_ISSET_ID = 2;
  private static final int __UPTIME_SECS_ISSET_ID = 3;
  private static final int __REQUESTED_MEMONHEAP_ISSET_ID = 4;
  private static final int __REQUESTED_MEMOFFHEAP_ISSET_ID = 5;
  private static final int __REQUESTED_CPU_ISSET_ID = 6;
  private static final int __ASSIGNED_MEMONHEAP_ISSET_ID = 7;
  private static final int __ASSIGNED_MEMOFFHEAP_ISSET_ID = 8;
  private static final int __ASSIGNED_CPU_ISSET_ID = 9;
  private short __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.SUPERVISOR_ID,_Fields.HOST,_Fields.PORT,_Fields.TOPOLOGY_ID,_Fields.TOPOLOGY_NAME,_Fields.NUM_EXECUTORS,_Fields.COMPONENT_TO_NUM_TASKS,_Fields.TIME_SECS,_Fields.UPTIME_SECS,_Fields.REQUESTED_MEMONHEAP,_Fields.REQUESTED_MEMOFFHEAP,_Fields.REQUESTED_CPU,_Fields.ASSIGNED_MEMONHEAP,_Fields.ASSIGNED_MEMOFFHEAP,_Fields.ASSIGNED_CPU,_Fields.OWNER};
  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.SUPERVISOR_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("supervisor_id", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.HOST, new org.apache.storm.thrift.meta_data.FieldMetaData("host", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.PORT, new org.apache.storm.thrift.meta_data.FieldMetaData("port", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.TOPOLOGY_ID, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_id", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOPOLOGY_NAME, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_name", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NUM_EXECUTORS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_executors", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.COMPONENT_TO_NUM_TASKS, new org.apache.storm.thrift.meta_data.FieldMetaData("component_to_num_tasks", 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.I64))));
    tmpMap.put(_Fields.TIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("time_secs", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.UPTIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("uptime_secs", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.REQUESTED_MEMONHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("requested_memonheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.REQUESTED_MEMOFFHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("requested_memoffheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.REQUESTED_CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("requested_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.ASSIGNED_MEMONHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("assigned_memonheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_MEMOFFHEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("assigned_memoffheap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.ASSIGNED_CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("assigned_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.OWNER, new org.apache.storm.thrift.meta_data.FieldMetaData("owner", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WorkerSummary.class, metaDataMap);
  }

  public WorkerSummary() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public WorkerSummary(WorkerSummary other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_supervisor_id()) {
      this.supervisor_id = other.supervisor_id;
    }
    if (other.is_set_host()) {
      this.host = other.host;
    }
    this.port = other.port;
    if (other.is_set_topology_id()) {
      this.topology_id = other.topology_id;
    }
    if (other.is_set_topology_name()) {
      this.topology_name = other.topology_name;
    }
    this.num_executors = other.num_executors;
    if (other.is_set_component_to_num_tasks()) {
      java.util.Map<java.lang.String,java.lang.Long> __this__component_to_num_tasks = new java.util.HashMap<java.lang.String,java.lang.Long>(other.component_to_num_tasks);
      this.component_to_num_tasks = __this__component_to_num_tasks;
    }
    this.time_secs = other.time_secs;
    this.uptime_secs = other.uptime_secs;
    this.requested_memonheap = other.requested_memonheap;
    this.requested_memoffheap = other.requested_memoffheap;
    this.requested_cpu = other.requested_cpu;
    this.assigned_memonheap = other.assigned_memonheap;
    this.assigned_memoffheap = other.assigned_memoffheap;
    this.assigned_cpu = other.assigned_cpu;
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
  }

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

  @Override
  public void clear() {
    this.supervisor_id = null;
    this.host = null;
    set_port_isSet(false);
    this.port = 0;
    this.topology_id = null;
    this.topology_name = null;
    set_num_executors_isSet(false);
    this.num_executors = 0;
    this.component_to_num_tasks = null;
    set_time_secs_isSet(false);
    this.time_secs = 0;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    set_requested_memonheap_isSet(false);
    this.requested_memonheap = 0.0;
    set_requested_memoffheap_isSet(false);
    this.requested_memoffheap = 0.0;
    set_requested_cpu_isSet(false);
    this.requested_cpu = 0.0;
    set_assigned_memonheap_isSet(false);
    this.assigned_memonheap = 0.0;
    set_assigned_memoffheap_isSet(false);
    this.assigned_memoffheap = 0.0;
    set_assigned_cpu_isSet(false);
    this.assigned_cpu = 0.0;
    this.owner = null;
  }

  @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_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_port() {
    return this.port;
  }

  public void set_port(int port) {
    this.port = port;
    set_port_isSet(true);
  }

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

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

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

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

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

  public void unset_topology_id() {
    this.topology_id = null;
  }

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

  public void set_topology_id_isSet(boolean value) {
    if (!value) {
      this.topology_id = null;
    }
  }

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

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

  public void unset_topology_name() {
    this.topology_name = null;
  }

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

  public void set_topology_name_isSet(boolean value) {
    if (!value) {
      this.topology_name = null;
    }
  }

  public int get_num_executors() {
    return this.num_executors;
  }

  public void set_num_executors(int num_executors) {
    this.num_executors = num_executors;
    set_num_executors_isSet(true);
  }

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

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

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

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

  public void put_to_component_to_num_tasks(java.lang.String key, long val) {
    if (this.component_to_num_tasks == null) {
      this.component_to_num_tasks = new java.util.HashMap<java.lang.String,java.lang.Long>();
    }
    this.component_to_num_tasks.put(key, val);
  }

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

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

  public void unset_component_to_num_tasks() {
    this.component_to_num_tasks = null;
  }

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

  public void set_component_to_num_tasks_isSet(boolean value) {
    if (!value) {
      this.component_to_num_tasks = null;
    }
  }

  public int get_time_secs() {
    return this.time_secs;
  }

  public void set_time_secs(int time_secs) {
    this.time_secs = time_secs;
    set_time_secs_isSet(true);
  }

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

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

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

  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 double get_requested_memonheap() {
    return this.requested_memonheap;
  }

  public void set_requested_memonheap(double requested_memonheap) {
    this.requested_memonheap = requested_memonheap;
    set_requested_memonheap_isSet(true);
  }

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

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

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

  public double get_requested_memoffheap() {
    return this.requested_memoffheap;
  }

  public void set_requested_memoffheap(double requested_memoffheap) {
    this.requested_memoffheap = requested_memoffheap;
    set_requested_memoffheap_isSet(true);
  }

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

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

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

  public double get_requested_cpu() {
    return this.requested_cpu;
  }

  public void set_requested_cpu(double requested_cpu) {
    this.requested_cpu = requested_cpu;
    set_requested_cpu_isSet(true);
  }

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

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

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

  public double get_assigned_memonheap() {
    return this.assigned_memonheap;
  }

  public void set_assigned_memonheap(double assigned_memonheap) {
    this.assigned_memonheap = assigned_memonheap;
    set_assigned_memonheap_isSet(true);
  }

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

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

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

  public double get_assigned_memoffheap() {
    return this.assigned_memoffheap;
  }

  public void set_assigned_memoffheap(double assigned_memoffheap) {
    this.assigned_memoffheap = assigned_memoffheap;
    set_assigned_memoffheap_isSet(true);
  }

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

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

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

  public double get_assigned_cpu() {
    return this.assigned_cpu;
  }

  public void set_assigned_cpu(double assigned_cpu) {
    this.assigned_cpu = assigned_cpu;
    set_assigned_cpu_isSet(true);
  }

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

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

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

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

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

  public void unset_owner() {
    this.owner = null;
  }

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

  public void set_owner_isSet(boolean value) {
    if (!value) {
      this.owner = null;
    }
  }

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

    case HOST:
      if (value == null) {
        unset_host();
      } else {
        set_host((java.lang.String)value);
      }
      break;

    case PORT:
      if (value == null) {
        unset_port();
      } else {
        set_port((java.lang.Integer)value);
      }
      break;

    case TOPOLOGY_ID:
      if (value == null) {
        unset_topology_id();
      } else {
        set_topology_id((java.lang.String)value);
      }
      break;

    case TOPOLOGY_NAME:
      if (value == null) {
        unset_topology_name();
      } else {
        set_topology_name((java.lang.String)value);
      }
      break;

    case NUM_EXECUTORS:
      if (value == null) {
        unset_num_executors();
      } else {
        set_num_executors((java.lang.Integer)value);
      }
      break;

    case COMPONENT_TO_NUM_TASKS:
      if (value == null) {
        unset_component_to_num_tasks();
      } else {
        set_component_to_num_tasks((java.util.Map<java.lang.String,java.lang.Long>)value);
      }
      break;

    case TIME_SECS:
      if (value == null) {
        unset_time_secs();
      } else {
        set_time_secs((java.lang.Integer)value);
      }
      break;

    case UPTIME_SECS:
      if (value == null) {
        unset_uptime_secs();
      } else {
        set_uptime_secs((java.lang.Integer)value);
      }
      break;

    case REQUESTED_MEMONHEAP:
      if (value == null) {
        unset_requested_memonheap();
      } else {
        set_requested_memonheap((java.lang.Double)value);
      }
      break;

    case REQUESTED_MEMOFFHEAP:
      if (value == null) {
        unset_requested_memoffheap();
      } else {
        set_requested_memoffheap((java.lang.Double)value);
      }
      break;

    case REQUESTED_CPU:
      if (value == null) {
        unset_requested_cpu();
      } else {
        set_requested_cpu((java.lang.Double)value);
      }
      break;

    case ASSIGNED_MEMONHEAP:
      if (value == null) {
        unset_assigned_memonheap();
      } else {
        set_assigned_memonheap((java.lang.Double)value);
      }
      break;

    case ASSIGNED_MEMOFFHEAP:
      if (value == null) {
        unset_assigned_memoffheap();
      } else {
        set_assigned_memoffheap((java.lang.Double)value);
      }
      break;

    case ASSIGNED_CPU:
      if (value == null) {
        unset_assigned_cpu();
      } else {
        set_assigned_cpu((java.lang.Double)value);
      }
      break;

    case OWNER:
      if (value == null) {
        unset_owner();
      } else {
        set_owner((java.lang.String)value);
      }
      break;

    }
  }

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

    case HOST:
      return get_host();

    case PORT:
      return get_port();

    case TOPOLOGY_ID:
      return get_topology_id();

    case TOPOLOGY_NAME:
      return get_topology_name();

    case NUM_EXECUTORS:
      return get_num_executors();

    case COMPONENT_TO_NUM_TASKS:
      return get_component_to_num_tasks();

    case TIME_SECS:
      return get_time_secs();

    case UPTIME_SECS:
      return get_uptime_secs();

    case REQUESTED_MEMONHEAP:
      return get_requested_memonheap();

    case REQUESTED_MEMOFFHEAP:
      return get_requested_memoffheap();

    case REQUESTED_CPU:
      return get_requested_cpu();

    case ASSIGNED_MEMONHEAP:
      return get_assigned_memonheap();

    case ASSIGNED_MEMOFFHEAP:
      return get_assigned_memoffheap();

    case ASSIGNED_CPU:
      return get_assigned_cpu();

    case OWNER:
      return get_owner();

    }
    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 SUPERVISOR_ID:
      return is_set_supervisor_id();
    case HOST:
      return is_set_host();
    case PORT:
      return is_set_port();
    case TOPOLOGY_ID:
      return is_set_topology_id();
    case TOPOLOGY_NAME:
      return is_set_topology_name();
    case NUM_EXECUTORS:
      return is_set_num_executors();
    case COMPONENT_TO_NUM_TASKS:
      return is_set_component_to_num_tasks();
    case TIME_SECS:
      return is_set_time_secs();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case REQUESTED_MEMONHEAP:
      return is_set_requested_memonheap();
    case REQUESTED_MEMOFFHEAP:
      return is_set_requested_memoffheap();
    case REQUESTED_CPU:
      return is_set_requested_cpu();
    case ASSIGNED_MEMONHEAP:
      return is_set_assigned_memonheap();
    case ASSIGNED_MEMOFFHEAP:
      return is_set_assigned_memoffheap();
    case ASSIGNED_CPU:
      return is_set_assigned_cpu();
    case OWNER:
      return is_set_owner();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    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_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_port = true && this.is_set_port();
    boolean that_present_port = true && that.is_set_port();
    if (this_present_port || that_present_port) {
      if (!(this_present_port && that_present_port))
        return false;
      if (this.port != that.port)
        return false;
    }

    boolean this_present_topology_id = true && this.is_set_topology_id();
    boolean that_present_topology_id = true && that.is_set_topology_id();
    if (this_present_topology_id || that_present_topology_id) {
      if (!(this_present_topology_id && that_present_topology_id))
        return false;
      if (!this.topology_id.equals(that.topology_id))
        return false;
    }

    boolean this_present_topology_name = true && this.is_set_topology_name();
    boolean that_present_topology_name = true && that.is_set_topology_name();
    if (this_present_topology_name || that_present_topology_name) {
      if (!(this_present_topology_name && that_present_topology_name))
        return false;
      if (!this.topology_name.equals(that.topology_name))
        return false;
    }

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

    boolean this_present_component_to_num_tasks = true && this.is_set_component_to_num_tasks();
    boolean that_present_component_to_num_tasks = true && that.is_set_component_to_num_tasks();
    if (this_present_component_to_num_tasks || that_present_component_to_num_tasks) {
      if (!(this_present_component_to_num_tasks && that_present_component_to_num_tasks))
        return false;
      if (!this.component_to_num_tasks.equals(that.component_to_num_tasks))
        return false;
    }

    boolean this_present_time_secs = true && this.is_set_time_secs();
    boolean that_present_time_secs = true && that.is_set_time_secs();
    if (this_present_time_secs || that_present_time_secs) {
      if (!(this_present_time_secs && that_present_time_secs))
        return false;
      if (this.time_secs != that.time_secs)
        return false;
    }

    boolean this_present_uptime_secs = true && this.is_set_uptime_secs();
    boolean that_present_uptime_secs = true && that.is_set_uptime_secs();
    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_requested_memonheap = true && this.is_set_requested_memonheap();
    boolean that_present_requested_memonheap = true && that.is_set_requested_memonheap();
    if (this_present_requested_memonheap || that_present_requested_memonheap) {
      if (!(this_present_requested_memonheap && that_present_requested_memonheap))
        return false;
      if (this.requested_memonheap != that.requested_memonheap)
        return false;
    }

    boolean this_present_requested_memoffheap = true && this.is_set_requested_memoffheap();
    boolean that_present_requested_memoffheap = true && that.is_set_requested_memoffheap();
    if (this_present_requested_memoffheap || that_present_requested_memoffheap) {
      if (!(this_present_requested_memoffheap && that_present_requested_memoffheap))
        return false;
      if (this.requested_memoffheap != that.requested_memoffheap)
        return false;
    }

    boolean this_present_requested_cpu = true && this.is_set_requested_cpu();
    boolean that_present_requested_cpu = true && that.is_set_requested_cpu();
    if (this_present_requested_cpu || that_present_requested_cpu) {
      if (!(this_present_requested_cpu && that_present_requested_cpu))
        return false;
      if (this.requested_cpu != that.requested_cpu)
        return false;
    }

    boolean this_present_assigned_memonheap = true && this.is_set_assigned_memonheap();
    boolean that_present_assigned_memonheap = true && that.is_set_assigned_memonheap();
    if (this_present_assigned_memonheap || that_present_assigned_memonheap) {
      if (!(this_present_assigned_memonheap && that_present_assigned_memonheap))
        return false;
      if (this.assigned_memonheap != that.assigned_memonheap)
        return false;
    }

    boolean this_present_assigned_memoffheap = true && this.is_set_assigned_memoffheap();
    boolean that_present_assigned_memoffheap = true && that.is_set_assigned_memoffheap();
    if (this_present_assigned_memoffheap || that_present_assigned_memoffheap) {
      if (!(this_present_assigned_memoffheap && that_present_assigned_memoffheap))
        return false;
      if (this.assigned_memoffheap != that.assigned_memoffheap)
        return false;
    }

    boolean this_present_assigned_cpu = true && this.is_set_assigned_cpu();
    boolean that_present_assigned_cpu = true && that.is_set_assigned_cpu();
    if (this_present_assigned_cpu || that_present_assigned_cpu) {
      if (!(this_present_assigned_cpu && that_present_assigned_cpu))
        return false;
      if (this.assigned_cpu != that.assigned_cpu)
        return false;
    }

    boolean this_present_owner = true && this.is_set_owner();
    boolean that_present_owner = true && that.is_set_owner();
    if (this_present_owner || that_present_owner) {
      if (!(this_present_owner && that_present_owner))
        return false;
      if (!this.owner.equals(that.owner))
        return false;
    }

    return true;
  }

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

    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_host()) ? 131071 : 524287);
    if (is_set_host())
      hashCode = hashCode * 8191 + host.hashCode();

    hashCode = hashCode * 8191 + ((is_set_port()) ? 131071 : 524287);
    if (is_set_port())
      hashCode = hashCode * 8191 + port;

    hashCode = hashCode * 8191 + ((is_set_topology_id()) ? 131071 : 524287);
    if (is_set_topology_id())
      hashCode = hashCode * 8191 + topology_id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_name()) ? 131071 : 524287);
    if (is_set_topology_name())
      hashCode = hashCode * 8191 + topology_name.hashCode();

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

    hashCode = hashCode * 8191 + ((is_set_component_to_num_tasks()) ? 131071 : 524287);
    if (is_set_component_to_num_tasks())
      hashCode = hashCode * 8191 + component_to_num_tasks.hashCode();

    hashCode = hashCode * 8191 + ((is_set_time_secs()) ? 131071 : 524287);
    if (is_set_time_secs())
      hashCode = hashCode * 8191 + time_secs;

    hashCode = hashCode * 8191 + ((is_set_uptime_secs()) ? 131071 : 524287);
    if (is_set_uptime_secs())
      hashCode = hashCode * 8191 + uptime_secs;

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

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

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

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

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

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

    hashCode = hashCode * 8191 + ((is_set_owner()) ? 131071 : 524287);
    if (is_set_owner())
      hashCode = hashCode * 8191 + owner.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    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_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_port()).compareTo(other.is_set_port());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_port()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.port, other.port);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_topology_id()).compareTo(other.is_set_topology_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_id()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_id, other.topology_id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_topology_name()).compareTo(other.is_set_topology_name());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_name()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_name, other.topology_name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_num_executors()).compareTo(other.is_set_num_executors());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_executors()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.num_executors, other.num_executors);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_component_to_num_tasks()).compareTo(other.is_set_component_to_num_tasks());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_component_to_num_tasks()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.component_to_num_tasks, other.component_to_num_tasks);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_time_secs()).compareTo(other.is_set_time_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_time_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.time_secs, other.time_secs);
      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_requested_memonheap()).compareTo(other.is_set_requested_memonheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_memonheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.requested_memonheap, other.requested_memonheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_requested_memoffheap()).compareTo(other.is_set_requested_memoffheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_memoffheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.requested_memoffheap, other.requested_memoffheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_requested_cpu()).compareTo(other.is_set_requested_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_requested_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.requested_cpu, other.requested_cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assigned_memonheap()).compareTo(other.is_set_assigned_memonheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_memonheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assigned_memonheap, other.assigned_memonheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assigned_memoffheap()).compareTo(other.is_set_assigned_memoffheap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_memoffheap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assigned_memoffheap, other.assigned_memoffheap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_assigned_cpu()).compareTo(other.is_set_assigned_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_assigned_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.assigned_cpu, other.assigned_cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_owner()).compareTo(other.is_set_owner());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_owner()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.owner, other.owner);
      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("WorkerSummary(");
    boolean first = true;

    if (is_set_supervisor_id()) {
      sb.append("supervisor_id:");
      if (this.supervisor_id == null) {
        sb.append("null");
      } else {
        sb.append(this.supervisor_id);
      }
      first = false;
    }
    if (is_set_host()) {
      if (!first) sb.append(", ");
      sb.append("host:");
      if (this.host == null) {
        sb.append("null");
      } else {
        sb.append(this.host);
      }
      first = false;
    }
    if (is_set_port()) {
      if (!first) sb.append(", ");
      sb.append("port:");
      sb.append(this.port);
      first = false;
    }
    if (is_set_topology_id()) {
      if (!first) sb.append(", ");
      sb.append("topology_id:");
      if (this.topology_id == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_id);
      }
      first = false;
    }
    if (is_set_topology_name()) {
      if (!first) sb.append(", ");
      sb.append("topology_name:");
      if (this.topology_name == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_name);
      }
      first = false;
    }
    if (is_set_num_executors()) {
      if (!first) sb.append(", ");
      sb.append("num_executors:");
      sb.append(this.num_executors);
      first = false;
    }
    if (is_set_component_to_num_tasks()) {
      if (!first) sb.append(", ");
      sb.append("component_to_num_tasks:");
      if (this.component_to_num_tasks == null) {
        sb.append("null");
      } else {
        sb.append(this.component_to_num_tasks);
      }
      first = false;
    }
    if (is_set_time_secs()) {
      if (!first) sb.append(", ");
      sb.append("time_secs:");
      sb.append(this.time_secs);
      first = false;
    }
    if (is_set_uptime_secs()) {
      if (!first) sb.append(", ");
      sb.append("uptime_secs:");
      sb.append(this.uptime_secs);
      first = false;
    }
    if (is_set_requested_memonheap()) {
      if (!first) sb.append(", ");
      sb.append("requested_memonheap:");
      sb.append(this.requested_memonheap);
      first = false;
    }
    if (is_set_requested_memoffheap()) {
      if (!first) sb.append(", ");
      sb.append("requested_memoffheap:");
      sb.append(this.requested_memoffheap);
      first = false;
    }
    if (is_set_requested_cpu()) {
      if (!first) sb.append(", ");
      sb.append("requested_cpu:");
      sb.append(this.requested_cpu);
      first = false;
    }
    if (is_set_assigned_memonheap()) {
      if (!first) sb.append(", ");
      sb.append("assigned_memonheap:");
      sb.append(this.assigned_memonheap);
      first = false;
    }
    if (is_set_assigned_memoffheap()) {
      if (!first) sb.append(", ");
      sb.append("assigned_memoffheap:");
      sb.append(this.assigned_memoffheap);
      first = false;
    }
    if (is_set_assigned_cpu()) {
      if (!first) sb.append(", ");
      sb.append("assigned_cpu:");
      sb.append(this.assigned_cpu);
      first = false;
    }
    if (is_set_owner()) {
      if (!first) sb.append(", ");
      sb.append("owner:");
      if (this.owner == null) {
        sb.append("null");
      } else {
        sb.append(this.owner);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

  private static class WorkerSummaryStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<WorkerSummary> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, WorkerSummary 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: // 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 2: // 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 3: // PORT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.port = iprot.readI32();
              struct.set_port_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // TOPOLOGY_ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_id = iprot.readString();
              struct.set_topology_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // TOPOLOGY_NAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_name = iprot.readString();
              struct.set_topology_name_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // NUM_EXECUTORS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_executors = iprot.readI32();
              struct.set_num_executors_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // COMPONENT_TO_NUM_TASKS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map486 = iprot.readMapBegin();
                struct.component_to_num_tasks = new java.util.HashMap<java.lang.String,java.lang.Long>(2*_map486.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key487;
                long _val488;
                for (int _i489 = 0; _i489 < _map486.size; ++_i489)
                {
                  _key487 = iprot.readString();
                  _val488 = iprot.readI64();
                  struct.component_to_num_tasks.put(_key487, _val488);
                }
                iprot.readMapEnd();
              }
              struct.set_component_to_num_tasks_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // TIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.time_secs = iprot.readI32();
              struct.set_time_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // 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 521: // REQUESTED_MEMONHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.requested_memonheap = iprot.readDouble();
              struct.set_requested_memonheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 522: // REQUESTED_MEMOFFHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.requested_memoffheap = iprot.readDouble();
              struct.set_requested_memoffheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 523: // REQUESTED_CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.requested_cpu = iprot.readDouble();
              struct.set_requested_cpu_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 524: // ASSIGNED_MEMONHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.assigned_memonheap = iprot.readDouble();
              struct.set_assigned_memonheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 525: // ASSIGNED_MEMOFFHEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.assigned_memoffheap = iprot.readDouble();
              struct.set_assigned_memoffheap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 526: // ASSIGNED_CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.assigned_cpu = iprot.readDouble();
              struct.set_assigned_cpu_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 527: // OWNER
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.owner = iprot.readString();
              struct.set_owner_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, WorkerSummary struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.supervisor_id != null) {
        if (struct.is_set_supervisor_id()) {
          oprot.writeFieldBegin(SUPERVISOR_ID_FIELD_DESC);
          oprot.writeString(struct.supervisor_id);
          oprot.writeFieldEnd();
        }
      }
      if (struct.host != null) {
        if (struct.is_set_host()) {
          oprot.writeFieldBegin(HOST_FIELD_DESC);
          oprot.writeString(struct.host);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_port()) {
        oprot.writeFieldBegin(PORT_FIELD_DESC);
        oprot.writeI32(struct.port);
        oprot.writeFieldEnd();
      }
      if (struct.topology_id != null) {
        if (struct.is_set_topology_id()) {
          oprot.writeFieldBegin(TOPOLOGY_ID_FIELD_DESC);
          oprot.writeString(struct.topology_id);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_name != null) {
        if (struct.is_set_topology_name()) {
          oprot.writeFieldBegin(TOPOLOGY_NAME_FIELD_DESC);
          oprot.writeString(struct.topology_name);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_num_executors()) {
        oprot.writeFieldBegin(NUM_EXECUTORS_FIELD_DESC);
        oprot.writeI32(struct.num_executors);
        oprot.writeFieldEnd();
      }
      if (struct.component_to_num_tasks != null) {
        if (struct.is_set_component_to_num_tasks()) {
          oprot.writeFieldBegin(COMPONENT_TO_NUM_TASKS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.I64, struct.component_to_num_tasks.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Long> _iter490 : struct.component_to_num_tasks.entrySet())
            {
              oprot.writeString(_iter490.getKey());
              oprot.writeI64(_iter490.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_time_secs()) {
        oprot.writeFieldBegin(TIME_SECS_FIELD_DESC);
        oprot.writeI32(struct.time_secs);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_uptime_secs()) {
        oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
        oprot.writeI32(struct.uptime_secs);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_memonheap()) {
        oprot.writeFieldBegin(REQUESTED_MEMONHEAP_FIELD_DESC);
        oprot.writeDouble(struct.requested_memonheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_memoffheap()) {
        oprot.writeFieldBegin(REQUESTED_MEMOFFHEAP_FIELD_DESC);
        oprot.writeDouble(struct.requested_memoffheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_requested_cpu()) {
        oprot.writeFieldBegin(REQUESTED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.requested_cpu);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_memonheap()) {
        oprot.writeFieldBegin(ASSIGNED_MEMONHEAP_FIELD_DESC);
        oprot.writeDouble(struct.assigned_memonheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_memoffheap()) {
        oprot.writeFieldBegin(ASSIGNED_MEMOFFHEAP_FIELD_DESC);
        oprot.writeDouble(struct.assigned_memoffheap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_assigned_cpu()) {
        oprot.writeFieldBegin(ASSIGNED_CPU_FIELD_DESC);
        oprot.writeDouble(struct.assigned_cpu);
        oprot.writeFieldEnd();
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class WorkerSummaryTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<WorkerSummary> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, WorkerSummary struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_supervisor_id()) {
        optionals.set(0);
      }
      if (struct.is_set_host()) {
        optionals.set(1);
      }
      if (struct.is_set_port()) {
        optionals.set(2);
      }
      if (struct.is_set_topology_id()) {
        optionals.set(3);
      }
      if (struct.is_set_topology_name()) {
        optionals.set(4);
      }
      if (struct.is_set_num_executors()) {
        optionals.set(5);
      }
      if (struct.is_set_component_to_num_tasks()) {
        optionals.set(6);
      }
      if (struct.is_set_time_secs()) {
        optionals.set(7);
      }
      if (struct.is_set_uptime_secs()) {
        optionals.set(8);
      }
      if (struct.is_set_requested_memonheap()) {
        optionals.set(9);
      }
      if (struct.is_set_requested_memoffheap()) {
        optionals.set(10);
      }
      if (struct.is_set_requested_cpu()) {
        optionals.set(11);
      }
      if (struct.is_set_assigned_memonheap()) {
        optionals.set(12);
      }
      if (struct.is_set_assigned_memoffheap()) {
        optionals.set(13);
      }
      if (struct.is_set_assigned_cpu()) {
        optionals.set(14);
      }
      if (struct.is_set_owner()) {
        optionals.set(15);
      }
      oprot.writeBitSet(optionals, 16);
      if (struct.is_set_supervisor_id()) {
        oprot.writeString(struct.supervisor_id);
      }
      if (struct.is_set_host()) {
        oprot.writeString(struct.host);
      }
      if (struct.is_set_port()) {
        oprot.writeI32(struct.port);
      }
      if (struct.is_set_topology_id()) {
        oprot.writeString(struct.topology_id);
      }
      if (struct.is_set_topology_name()) {
        oprot.writeString(struct.topology_name);
      }
      if (struct.is_set_num_executors()) {
        oprot.writeI32(struct.num_executors);
      }
      if (struct.is_set_component_to_num_tasks()) {
        {
          oprot.writeI32(struct.component_to_num_tasks.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Long> _iter491 : struct.component_to_num_tasks.entrySet())
          {
            oprot.writeString(_iter491.getKey());
            oprot.writeI64(_iter491.getValue());
          }
        }
      }
      if (struct.is_set_time_secs()) {
        oprot.writeI32(struct.time_secs);
      }
      if (struct.is_set_uptime_secs()) {
        oprot.writeI32(struct.uptime_secs);
      }
      if (struct.is_set_requested_memonheap()) {
        oprot.writeDouble(struct.requested_memonheap);
      }
      if (struct.is_set_requested_memoffheap()) {
        oprot.writeDouble(struct.requested_memoffheap);
      }
      if (struct.is_set_requested_cpu()) {
        oprot.writeDouble(struct.requested_cpu);
      }
      if (struct.is_set_assigned_memonheap()) {
        oprot.writeDouble(struct.assigned_memonheap);
      }
      if (struct.is_set_assigned_memoffheap()) {
        oprot.writeDouble(struct.assigned_memoffheap);
      }
      if (struct.is_set_assigned_cpu()) {
        oprot.writeDouble(struct.assigned_cpu);
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, WorkerSummary struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(16);
      if (incoming.get(0)) {
        struct.supervisor_id = iprot.readString();
        struct.set_supervisor_id_isSet(true);
      }
      if (incoming.get(1)) {
        struct.host = iprot.readString();
        struct.set_host_isSet(true);
      }
      if (incoming.get(2)) {
        struct.port = iprot.readI32();
        struct.set_port_isSet(true);
      }
      if (incoming.get(3)) {
        struct.topology_id = iprot.readString();
        struct.set_topology_id_isSet(true);
      }
      if (incoming.get(4)) {
        struct.topology_name = iprot.readString();
        struct.set_topology_name_isSet(true);
      }
      if (incoming.get(5)) {
        struct.num_executors = iprot.readI32();
        struct.set_num_executors_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.storm.thrift.protocol.TMap _map492 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
          struct.component_to_num_tasks = new java.util.HashMap<java.lang.String,java.lang.Long>(2*_map492.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key493;
          long _val494;
          for (int _i495 = 0; _i495 < _map492.size; ++_i495)
          {
            _key493 = iprot.readString();
            _val494 = iprot.readI64();
            struct.component_to_num_tasks.put(_key493, _val494);
          }
        }
        struct.set_component_to_num_tasks_isSet(true);
      }
      if (incoming.get(7)) {
        struct.time_secs = iprot.readI32();
        struct.set_time_secs_isSet(true);
      }
      if (incoming.get(8)) {
        struct.uptime_secs = iprot.readI32();
        struct.set_uptime_secs_isSet(true);
      }
      if (incoming.get(9)) {
        struct.requested_memonheap = iprot.readDouble();
        struct.set_requested_memonheap_isSet(true);
      }
      if (incoming.get(10)) {
        struct.requested_memoffheap = iprot.readDouble();
        struct.set_requested_memoffheap_isSet(true);
      }
      if (incoming.get(11)) {
        struct.requested_cpu = iprot.readDouble();
        struct.set_requested_cpu_isSet(true);
      }
      if (incoming.get(12)) {
        struct.assigned_memonheap = iprot.readDouble();
        struct.set_assigned_memonheap_isSet(true);
      }
      if (incoming.get(13)) {
        struct.assigned_memoffheap = iprot.readDouble();
        struct.set_assigned_memoffheap_isSet(true);
      }
      if (incoming.get(14)) {
        struct.assigned_cpu = iprot.readDouble();
        struct.set_assigned_cpu_isSet(true);
      }
      if (incoming.get(15)) {
        struct.owner = iprot.readString();
        struct.set_owner_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();
  }
}

