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

  private static final org.apache.storm.thrift.protocol.TField ID_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("id", org.apache.storm.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.storm.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("name", org.apache.storm.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.storm.thrift.protocol.TField NUM_TASKS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("num_tasks", org.apache.storm.thrift.protocol.TType.I32, (short)3);
  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)4);
  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)5);
  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)6);
  private static final org.apache.storm.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("status", org.apache.storm.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.storm.thrift.protocol.TField STORM_VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("storm_version", org.apache.storm.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.storm.thrift.protocol.TField TOPOLOGY_VERSION_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("topology_version", org.apache.storm.thrift.protocol.TType.STRING, (short)9);
  private static final org.apache.storm.thrift.protocol.TField SCHED_STATUS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("sched_status", org.apache.storm.thrift.protocol.TType.STRING, (short)513);
  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)514);
  private static final org.apache.storm.thrift.protocol.TField REPLICATION_COUNT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("replication_count", org.apache.storm.thrift.protocol.TType.I32, (short)515);
  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.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TopologySummaryStandardSchemeFactory();
  private static final org.apache.storm.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TopologySummaryTupleSchemeFactory();

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String id; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String name; // required
  private int num_tasks; // required
  private int num_executors; // required
  private int num_workers; // required
  private int uptime_secs; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String status; // required
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String storm_version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String topology_version; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String sched_status; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String owner; // optional
  private int replication_count; // 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

  /** 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 {
    ID((short)1, "id"),
    NAME((short)2, "name"),
    NUM_TASKS((short)3, "num_tasks"),
    NUM_EXECUTORS((short)4, "num_executors"),
    NUM_WORKERS((short)5, "num_workers"),
    UPTIME_SECS((short)6, "uptime_secs"),
    STATUS((short)7, "status"),
    STORM_VERSION((short)8, "storm_version"),
    TOPOLOGY_VERSION((short)9, "topology_version"),
    SCHED_STATUS((short)513, "sched_status"),
    OWNER((short)514, "owner"),
    REPLICATION_COUNT((short)515, "replication_count"),
    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");

    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: // ID
          return ID;
        case 2: // NAME
          return NAME;
        case 3: // NUM_TASKS
          return NUM_TASKS;
        case 4: // NUM_EXECUTORS
          return NUM_EXECUTORS;
        case 5: // NUM_WORKERS
          return NUM_WORKERS;
        case 6: // UPTIME_SECS
          return UPTIME_SECS;
        case 7: // STATUS
          return STATUS;
        case 8: // STORM_VERSION
          return STORM_VERSION;
        case 9: // TOPOLOGY_VERSION
          return TOPOLOGY_VERSION;
        case 513: // SCHED_STATUS
          return SCHED_STATUS;
        case 514: // OWNER
          return OWNER;
        case 515: // REPLICATION_COUNT
          return REPLICATION_COUNT;
        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;
        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 __NUM_TASKS_ISSET_ID = 0;
  private static final int __NUM_EXECUTORS_ISSET_ID = 1;
  private static final int __NUM_WORKERS_ISSET_ID = 2;
  private static final int __UPTIME_SECS_ISSET_ID = 3;
  private static final int __REPLICATION_COUNT_ISSET_ID = 4;
  private static final int __REQUESTED_MEMONHEAP_ISSET_ID = 5;
  private static final int __REQUESTED_MEMOFFHEAP_ISSET_ID = 6;
  private static final int __REQUESTED_CPU_ISSET_ID = 7;
  private static final int __ASSIGNED_MEMONHEAP_ISSET_ID = 8;
  private static final int __ASSIGNED_MEMOFFHEAP_ISSET_ID = 9;
  private static final int __ASSIGNED_CPU_ISSET_ID = 10;
  private short __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.STORM_VERSION,_Fields.TOPOLOGY_VERSION,_Fields.SCHED_STATUS,_Fields.OWNER,_Fields.REPLICATION_COUNT,_Fields.REQUESTED_MEMONHEAP,_Fields.REQUESTED_MEMOFFHEAP,_Fields.REQUESTED_CPU,_Fields.ASSIGNED_MEMONHEAP,_Fields.ASSIGNED_MEMOFFHEAP,_Fields.ASSIGNED_CPU};
  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.ID, new org.apache.storm.thrift.meta_data.FieldMetaData("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.NAME, new org.apache.storm.thrift.meta_data.FieldMetaData("name", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NUM_TASKS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_tasks", 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_EXECUTORS, new org.apache.storm.thrift.meta_data.FieldMetaData("num_executors", 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.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.STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("status", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.STORM_VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("storm_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.TOPOLOGY_VERSION, new org.apache.storm.thrift.meta_data.FieldMetaData("topology_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.SCHED_STATUS, new org.apache.storm.thrift.meta_data.FieldMetaData("sched_status", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    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)));
    tmpMap.put(_Fields.REPLICATION_COUNT, new org.apache.storm.thrift.meta_data.FieldMetaData("replication_count", 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)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TopologySummary.class, metaDataMap);
  }

  public TopologySummary() {
  }

  public TopologySummary(
    java.lang.String id,
    java.lang.String name,
    int num_tasks,
    int num_executors,
    int num_workers,
    int uptime_secs,
    java.lang.String status)
  {
    this();
    this.id = id;
    this.name = name;
    this.num_tasks = num_tasks;
    set_num_tasks_isSet(true);
    this.num_executors = num_executors;
    set_num_executors_isSet(true);
    this.num_workers = num_workers;
    set_num_workers_isSet(true);
    this.uptime_secs = uptime_secs;
    set_uptime_secs_isSet(true);
    this.status = status;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TopologySummary(TopologySummary other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.is_set_id()) {
      this.id = other.id;
    }
    if (other.is_set_name()) {
      this.name = other.name;
    }
    this.num_tasks = other.num_tasks;
    this.num_executors = other.num_executors;
    this.num_workers = other.num_workers;
    this.uptime_secs = other.uptime_secs;
    if (other.is_set_status()) {
      this.status = other.status;
    }
    if (other.is_set_storm_version()) {
      this.storm_version = other.storm_version;
    }
    if (other.is_set_topology_version()) {
      this.topology_version = other.topology_version;
    }
    if (other.is_set_sched_status()) {
      this.sched_status = other.sched_status;
    }
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
    this.replication_count = other.replication_count;
    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;
  }

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

  @Override
  public void clear() {
    this.id = null;
    this.name = null;
    set_num_tasks_isSet(false);
    this.num_tasks = 0;
    set_num_executors_isSet(false);
    this.num_executors = 0;
    set_num_workers_isSet(false);
    this.num_workers = 0;
    set_uptime_secs_isSet(false);
    this.uptime_secs = 0;
    this.status = null;
    this.storm_version = null;
    this.topology_version = null;
    this.sched_status = null;
    this.owner = null;
    set_replication_count_isSet(false);
    this.replication_count = 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;
  }

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

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

  public void unset_id() {
    this.id = null;
  }

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

  public void set_id_isSet(boolean value) {
    if (!value) {
      this.id = null;
    }
  }

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

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

  public void unset_name() {
    this.name = null;
  }

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

  public void set_name_isSet(boolean value) {
    if (!value) {
      this.name = null;
    }
  }

  public int get_num_tasks() {
    return this.num_tasks;
  }

  public void set_num_tasks(int num_tasks) {
    this.num_tasks = num_tasks;
    set_num_tasks_isSet(true);
  }

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

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

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

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

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

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

  public void unset_status() {
    this.status = null;
  }

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

  public void set_status_isSet(boolean value) {
    if (!value) {
      this.status = null;
    }
  }

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

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

  public void unset_storm_version() {
    this.storm_version = null;
  }

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

  public void set_storm_version_isSet(boolean value) {
    if (!value) {
      this.storm_version = null;
    }
  }

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

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

  public void unset_topology_version() {
    this.topology_version = null;
  }

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

  public void set_topology_version_isSet(boolean value) {
    if (!value) {
      this.topology_version = null;
    }
  }

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

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

  public void unset_sched_status() {
    this.sched_status = null;
  }

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

  public void set_sched_status_isSet(boolean value) {
    if (!value) {
      this.sched_status = null;
    }
  }

  @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 int get_replication_count() {
    return this.replication_count;
  }

  public void set_replication_count(int replication_count) {
    this.replication_count = replication_count;
    set_replication_count_isSet(true);
  }

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

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

  public void set_replication_count_isSet(boolean value) {
    __isset_bitfield = org.apache.storm.thrift.EncodingUtils.setBit(__isset_bitfield, __REPLICATION_COUNT_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);
  }

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

    case NAME:
      if (value == null) {
        unset_name();
      } else {
        set_name((java.lang.String)value);
      }
      break;

    case NUM_TASKS:
      if (value == null) {
        unset_num_tasks();
      } else {
        set_num_tasks((java.lang.Integer)value);
      }
      break;

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

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

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

    case STATUS:
      if (value == null) {
        unset_status();
      } else {
        set_status((java.lang.String)value);
      }
      break;

    case STORM_VERSION:
      if (value == null) {
        unset_storm_version();
      } else {
        set_storm_version((java.lang.String)value);
      }
      break;

    case TOPOLOGY_VERSION:
      if (value == null) {
        unset_topology_version();
      } else {
        set_topology_version((java.lang.String)value);
      }
      break;

    case SCHED_STATUS:
      if (value == null) {
        unset_sched_status();
      } else {
        set_sched_status((java.lang.String)value);
      }
      break;

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

    case REPLICATION_COUNT:
      if (value == null) {
        unset_replication_count();
      } else {
        set_replication_count((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;

    }
  }

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

    case NAME:
      return get_name();

    case NUM_TASKS:
      return get_num_tasks();

    case NUM_EXECUTORS:
      return get_num_executors();

    case NUM_WORKERS:
      return get_num_workers();

    case UPTIME_SECS:
      return get_uptime_secs();

    case STATUS:
      return get_status();

    case STORM_VERSION:
      return get_storm_version();

    case TOPOLOGY_VERSION:
      return get_topology_version();

    case SCHED_STATUS:
      return get_sched_status();

    case OWNER:
      return get_owner();

    case REPLICATION_COUNT:
      return get_replication_count();

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

    }
    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 ID:
      return is_set_id();
    case NAME:
      return is_set_name();
    case NUM_TASKS:
      return is_set_num_tasks();
    case NUM_EXECUTORS:
      return is_set_num_executors();
    case NUM_WORKERS:
      return is_set_num_workers();
    case UPTIME_SECS:
      return is_set_uptime_secs();
    case STATUS:
      return is_set_status();
    case STORM_VERSION:
      return is_set_storm_version();
    case TOPOLOGY_VERSION:
      return is_set_topology_version();
    case SCHED_STATUS:
      return is_set_sched_status();
    case OWNER:
      return is_set_owner();
    case REPLICATION_COUNT:
      return is_set_replication_count();
    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();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_id = true && this.is_set_id();
    boolean that_present_id = true && that.is_set_id();
    if (this_present_id || that_present_id) {
      if (!(this_present_id && that_present_id))
        return false;
      if (!this.id.equals(that.id))
        return false;
    }

    boolean this_present_name = true && this.is_set_name();
    boolean that_present_name = true && that.is_set_name();
    if (this_present_name || that_present_name) {
      if (!(this_present_name && that_present_name))
        return false;
      if (!this.name.equals(that.name))
        return false;
    }

    boolean this_present_num_tasks = true;
    boolean that_present_num_tasks = true;
    if (this_present_num_tasks || that_present_num_tasks) {
      if (!(this_present_num_tasks && that_present_num_tasks))
        return false;
      if (this.num_tasks != that.num_tasks)
        return false;
    }

    boolean this_present_num_executors = true;
    boolean that_present_num_executors = true;
    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_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_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_status = true && this.is_set_status();
    boolean that_present_status = true && that.is_set_status();
    if (this_present_status || that_present_status) {
      if (!(this_present_status && that_present_status))
        return false;
      if (!this.status.equals(that.status))
        return false;
    }

    boolean this_present_storm_version = true && this.is_set_storm_version();
    boolean that_present_storm_version = true && that.is_set_storm_version();
    if (this_present_storm_version || that_present_storm_version) {
      if (!(this_present_storm_version && that_present_storm_version))
        return false;
      if (!this.storm_version.equals(that.storm_version))
        return false;
    }

    boolean this_present_topology_version = true && this.is_set_topology_version();
    boolean that_present_topology_version = true && that.is_set_topology_version();
    if (this_present_topology_version || that_present_topology_version) {
      if (!(this_present_topology_version && that_present_topology_version))
        return false;
      if (!this.topology_version.equals(that.topology_version))
        return false;
    }

    boolean this_present_sched_status = true && this.is_set_sched_status();
    boolean that_present_sched_status = true && that.is_set_sched_status();
    if (this_present_sched_status || that_present_sched_status) {
      if (!(this_present_sched_status && that_present_sched_status))
        return false;
      if (!this.sched_status.equals(that.sched_status))
        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;
    }

    boolean this_present_replication_count = true && this.is_set_replication_count();
    boolean that_present_replication_count = true && that.is_set_replication_count();
    if (this_present_replication_count || that_present_replication_count) {
      if (!(this_present_replication_count && that_present_replication_count))
        return false;
      if (this.replication_count != that.replication_count)
        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;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_id()) ? 131071 : 524287);
    if (is_set_id())
      hashCode = hashCode * 8191 + id.hashCode();

    hashCode = hashCode * 8191 + ((is_set_name()) ? 131071 : 524287);
    if (is_set_name())
      hashCode = hashCode * 8191 + name.hashCode();

    hashCode = hashCode * 8191 + num_tasks;

    hashCode = hashCode * 8191 + num_executors;

    hashCode = hashCode * 8191 + num_workers;

    hashCode = hashCode * 8191 + uptime_secs;

    hashCode = hashCode * 8191 + ((is_set_status()) ? 131071 : 524287);
    if (is_set_status())
      hashCode = hashCode * 8191 + status.hashCode();

    hashCode = hashCode * 8191 + ((is_set_storm_version()) ? 131071 : 524287);
    if (is_set_storm_version())
      hashCode = hashCode * 8191 + storm_version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_topology_version()) ? 131071 : 524287);
    if (is_set_topology_version())
      hashCode = hashCode * 8191 + topology_version.hashCode();

    hashCode = hashCode * 8191 + ((is_set_sched_status()) ? 131071 : 524287);
    if (is_set_sched_status())
      hashCode = hashCode * 8191 + sched_status.hashCode();

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

    hashCode = hashCode * 8191 + ((is_set_replication_count()) ? 131071 : 524287);
    if (is_set_replication_count())
      hashCode = hashCode * 8191 + replication_count;

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

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_id()).compareTo(other.is_set_id());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_id()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.id, other.id);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_name()).compareTo(other.is_set_name());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_name()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.name, other.name);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_num_tasks()).compareTo(other.is_set_num_tasks());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_num_tasks()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.num_tasks, other.num_tasks);
      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_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_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_status()).compareTo(other.is_set_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_status()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.status, other.status);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_storm_version()).compareTo(other.is_set_storm_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_storm_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.storm_version, other.storm_version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_topology_version()).compareTo(other.is_set_topology_version());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_topology_version()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.topology_version, other.topology_version);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_sched_status()).compareTo(other.is_set_sched_status());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_sched_status()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.sched_status, other.sched_status);
      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;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_replication_count()).compareTo(other.is_set_replication_count());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_replication_count()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.replication_count, other.replication_count);
      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;
      }
    }
    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("TopologySummary(");
    boolean first = true;

    sb.append("id:");
    if (this.id == null) {
      sb.append("null");
    } else {
      sb.append(this.id);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("name:");
    if (this.name == null) {
      sb.append("null");
    } else {
      sb.append(this.name);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("num_tasks:");
    sb.append(this.num_tasks);
    first = false;
    if (!first) sb.append(", ");
    sb.append("num_executors:");
    sb.append(this.num_executors);
    first = false;
    if (!first) sb.append(", ");
    sb.append("num_workers:");
    sb.append(this.num_workers);
    first = false;
    if (!first) sb.append(", ");
    sb.append("uptime_secs:");
    sb.append(this.uptime_secs);
    first = false;
    if (!first) sb.append(", ");
    sb.append("status:");
    if (this.status == null) {
      sb.append("null");
    } else {
      sb.append(this.status);
    }
    first = false;
    if (is_set_storm_version()) {
      if (!first) sb.append(", ");
      sb.append("storm_version:");
      if (this.storm_version == null) {
        sb.append("null");
      } else {
        sb.append(this.storm_version);
      }
      first = false;
    }
    if (is_set_topology_version()) {
      if (!first) sb.append(", ");
      sb.append("topology_version:");
      if (this.topology_version == null) {
        sb.append("null");
      } else {
        sb.append(this.topology_version);
      }
      first = false;
    }
    if (is_set_sched_status()) {
      if (!first) sb.append(", ");
      sb.append("sched_status:");
      if (this.sched_status == null) {
        sb.append("null");
      } else {
        sb.append(this.sched_status);
      }
      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;
    }
    if (is_set_replication_count()) {
      if (!first) sb.append(", ");
      sb.append("replication_count:");
      sb.append(this.replication_count);
      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;
    }
    sb.append(")");
    return sb.toString();
  }

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

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

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

    if (!is_set_num_executors()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'num_executors' 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_uptime_secs()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'uptime_secs' is unset! Struct:" + toString());
    }

    if (!is_set_status()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'status' 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 TopologySummaryStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public TopologySummaryStandardScheme getScheme() {
      return new TopologySummaryStandardScheme();
    }
  }

  private static class TopologySummaryStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<TopologySummary> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, TopologySummary 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: // ID
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.id = iprot.readString();
              struct.set_id_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // NAME
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.name = iprot.readString();
              struct.set_name_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // NUM_TASKS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.num_tasks = iprot.readI32();
              struct.set_num_tasks_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // 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 5: // 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 6: // 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 7: // STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.status = iprot.readString();
              struct.set_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // STORM_VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.storm_version = iprot.readString();
              struct.set_storm_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // TOPOLOGY_VERSION
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.topology_version = iprot.readString();
              struct.set_topology_version_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 513: // SCHED_STATUS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.sched_status = iprot.readString();
              struct.set_sched_status_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 514: // 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;
          case 515: // REPLICATION_COUNT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.I32) {
              struct.replication_count = iprot.readI32();
              struct.set_replication_count_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;
          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, TopologySummary struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.id != null) {
        oprot.writeFieldBegin(ID_FIELD_DESC);
        oprot.writeString(struct.id);
        oprot.writeFieldEnd();
      }
      if (struct.name != null) {
        oprot.writeFieldBegin(NAME_FIELD_DESC);
        oprot.writeString(struct.name);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(NUM_TASKS_FIELD_DESC);
      oprot.writeI32(struct.num_tasks);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(NUM_EXECUTORS_FIELD_DESC);
      oprot.writeI32(struct.num_executors);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(NUM_WORKERS_FIELD_DESC);
      oprot.writeI32(struct.num_workers);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(UPTIME_SECS_FIELD_DESC);
      oprot.writeI32(struct.uptime_secs);
      oprot.writeFieldEnd();
      if (struct.status != null) {
        oprot.writeFieldBegin(STATUS_FIELD_DESC);
        oprot.writeString(struct.status);
        oprot.writeFieldEnd();
      }
      if (struct.storm_version != null) {
        if (struct.is_set_storm_version()) {
          oprot.writeFieldBegin(STORM_VERSION_FIELD_DESC);
          oprot.writeString(struct.storm_version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.topology_version != null) {
        if (struct.is_set_topology_version()) {
          oprot.writeFieldBegin(TOPOLOGY_VERSION_FIELD_DESC);
          oprot.writeString(struct.topology_version);
          oprot.writeFieldEnd();
        }
      }
      if (struct.sched_status != null) {
        if (struct.is_set_sched_status()) {
          oprot.writeFieldBegin(SCHED_STATUS_FIELD_DESC);
          oprot.writeString(struct.sched_status);
          oprot.writeFieldEnd();
        }
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      if (struct.is_set_replication_count()) {
        oprot.writeFieldBegin(REPLICATION_COUNT_FIELD_DESC);
        oprot.writeI32(struct.replication_count);
        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();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class TopologySummaryTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<TopologySummary> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, TopologySummary struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.id);
      oprot.writeString(struct.name);
      oprot.writeI32(struct.num_tasks);
      oprot.writeI32(struct.num_executors);
      oprot.writeI32(struct.num_workers);
      oprot.writeI32(struct.uptime_secs);
      oprot.writeString(struct.status);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_storm_version()) {
        optionals.set(0);
      }
      if (struct.is_set_topology_version()) {
        optionals.set(1);
      }
      if (struct.is_set_sched_status()) {
        optionals.set(2);
      }
      if (struct.is_set_owner()) {
        optionals.set(3);
      }
      if (struct.is_set_replication_count()) {
        optionals.set(4);
      }
      if (struct.is_set_requested_memonheap()) {
        optionals.set(5);
      }
      if (struct.is_set_requested_memoffheap()) {
        optionals.set(6);
      }
      if (struct.is_set_requested_cpu()) {
        optionals.set(7);
      }
      if (struct.is_set_assigned_memonheap()) {
        optionals.set(8);
      }
      if (struct.is_set_assigned_memoffheap()) {
        optionals.set(9);
      }
      if (struct.is_set_assigned_cpu()) {
        optionals.set(10);
      }
      oprot.writeBitSet(optionals, 11);
      if (struct.is_set_storm_version()) {
        oprot.writeString(struct.storm_version);
      }
      if (struct.is_set_topology_version()) {
        oprot.writeString(struct.topology_version);
      }
      if (struct.is_set_sched_status()) {
        oprot.writeString(struct.sched_status);
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
      if (struct.is_set_replication_count()) {
        oprot.writeI32(struct.replication_count);
      }
      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);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, TopologySummary struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.id = iprot.readString();
      struct.set_id_isSet(true);
      struct.name = iprot.readString();
      struct.set_name_isSet(true);
      struct.num_tasks = iprot.readI32();
      struct.set_num_tasks_isSet(true);
      struct.num_executors = iprot.readI32();
      struct.set_num_executors_isSet(true);
      struct.num_workers = iprot.readI32();
      struct.set_num_workers_isSet(true);
      struct.uptime_secs = iprot.readI32();
      struct.set_uptime_secs_isSet(true);
      struct.status = iprot.readString();
      struct.set_status_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(11);
      if (incoming.get(0)) {
        struct.storm_version = iprot.readString();
        struct.set_storm_version_isSet(true);
      }
      if (incoming.get(1)) {
        struct.topology_version = iprot.readString();
        struct.set_topology_version_isSet(true);
      }
      if (incoming.get(2)) {
        struct.sched_status = iprot.readString();
        struct.set_sched_status_isSet(true);
      }
      if (incoming.get(3)) {
        struct.owner = iprot.readString();
        struct.set_owner_isSet(true);
      }
      if (incoming.get(4)) {
        struct.replication_count = iprot.readI32();
        struct.set_replication_count_isSet(true);
      }
      if (incoming.get(5)) {
        struct.requested_memonheap = iprot.readDouble();
        struct.set_requested_memonheap_isSet(true);
      }
      if (incoming.get(6)) {
        struct.requested_memoffheap = iprot.readDouble();
        struct.set_requested_memoffheap_isSet(true);
      }
      if (incoming.get(7)) {
        struct.requested_cpu = iprot.readDouble();
        struct.set_requested_cpu_isSet(true);
      }
      if (incoming.get(8)) {
        struct.assigned_memonheap = iprot.readDouble();
        struct.set_assigned_memonheap_isSet(true);
      }
      if (incoming.get(9)) {
        struct.assigned_memoffheap = iprot.readDouble();
        struct.set_assigned_memoffheap_isSet(true);
      }
      if (incoming.get(10)) {
        struct.assigned_cpu = iprot.readDouble();
        struct.set_assigned_cpu_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();
  }
}

