/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Autogenerated by Thrift Compiler (0.13.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.storm.generated;

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

  private static final org.apache.storm.thrift.protocol.TField MEM_ON_HEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("mem_on_heap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)1);
  private static final org.apache.storm.thrift.protocol.TField MEM_OFF_HEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("mem_off_heap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)2);
  private static final org.apache.storm.thrift.protocol.TField CPU_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("cpu", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)3);
  private static final org.apache.storm.thrift.protocol.TField SHARED_MEM_ON_HEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("shared_mem_on_heap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)4);
  private static final org.apache.storm.thrift.protocol.TField SHARED_MEM_OFF_HEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("shared_mem_off_heap", org.apache.storm.thrift.protocol.TType.DOUBLE, (short)5);
  private static final org.apache.storm.thrift.protocol.TField RESOURCES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("resources", org.apache.storm.thrift.protocol.TType.MAP, (short)6);
  private static final org.apache.storm.thrift.protocol.TField SHARED_RESOURCES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("shared_resources", org.apache.storm.thrift.protocol.TType.MAP, (short)7);

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

  private double mem_on_heap; // optional
  private double mem_off_heap; // optional
  private double cpu; // optional
  private double shared_mem_on_heap; // optional
  private double shared_mem_off_heap; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> resources; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> shared_resources; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
    MEM_ON_HEAP((short)1, "mem_on_heap"),
    MEM_OFF_HEAP((short)2, "mem_off_heap"),
    CPU((short)3, "cpu"),
    SHARED_MEM_ON_HEAP((short)4, "shared_mem_on_heap"),
    SHARED_MEM_OFF_HEAP((short)5, "shared_mem_off_heap"),
    RESOURCES((short)6, "resources"),
    SHARED_RESOURCES((short)7, "shared_resources");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.storm.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // MEM_ON_HEAP
          return MEM_ON_HEAP;
        case 2: // MEM_OFF_HEAP
          return MEM_OFF_HEAP;
        case 3: // CPU
          return CPU;
        case 4: // SHARED_MEM_ON_HEAP
          return SHARED_MEM_ON_HEAP;
        case 5: // SHARED_MEM_OFF_HEAP
          return SHARED_MEM_OFF_HEAP;
        case 6: // RESOURCES
          return RESOURCES;
        case 7: // SHARED_RESOURCES
          return SHARED_RESOURCES;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __MEM_ON_HEAP_ISSET_ID = 0;
  private static final int __MEM_OFF_HEAP_ISSET_ID = 1;
  private static final int __CPU_ISSET_ID = 2;
  private static final int __SHARED_MEM_ON_HEAP_ISSET_ID = 3;
  private static final int __SHARED_MEM_OFF_HEAP_ISSET_ID = 4;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.MEM_ON_HEAP,_Fields.MEM_OFF_HEAP,_Fields.CPU,_Fields.SHARED_MEM_ON_HEAP,_Fields.SHARED_MEM_OFF_HEAP,_Fields.RESOURCES,_Fields.SHARED_RESOURCES};
  public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.MEM_ON_HEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("mem_on_heap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.MEM_OFF_HEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("mem_off_heap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.CPU, new org.apache.storm.thrift.meta_data.FieldMetaData("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.SHARED_MEM_ON_HEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("shared_mem_on_heap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.SHARED_MEM_OFF_HEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("shared_mem_off_heap", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)));
    tmpMap.put(_Fields.RESOURCES, new org.apache.storm.thrift.meta_data.FieldMetaData("resources", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE))));
    tmpMap.put(_Fields.SHARED_RESOURCES, new org.apache.storm.thrift.meta_data.FieldMetaData("shared_resources", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WorkerResources.class, metaDataMap);
  }

  public WorkerResources() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public WorkerResources(WorkerResources other) {
    __isset_bitfield = other.__isset_bitfield;
    this.mem_on_heap = other.mem_on_heap;
    this.mem_off_heap = other.mem_off_heap;
    this.cpu = other.cpu;
    this.shared_mem_on_heap = other.shared_mem_on_heap;
    this.shared_mem_off_heap = other.shared_mem_off_heap;
    if (other.is_set_resources()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__resources = new java.util.HashMap<java.lang.String,java.lang.Double>(other.resources);
      this.resources = __this__resources;
    }
    if (other.is_set_shared_resources()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__shared_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(other.shared_resources);
      this.shared_resources = __this__shared_resources;
    }
  }

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

  @Override
  public void clear() {
    set_mem_on_heap_isSet(false);
    this.mem_on_heap = 0.0;
    set_mem_off_heap_isSet(false);
    this.mem_off_heap = 0.0;
    set_cpu_isSet(false);
    this.cpu = 0.0;
    set_shared_mem_on_heap_isSet(false);
    this.shared_mem_on_heap = 0.0;
    set_shared_mem_off_heap_isSet(false);
    this.shared_mem_off_heap = 0.0;
    this.resources = null;
    this.shared_resources = null;
  }

  public double get_mem_on_heap() {
    return this.mem_on_heap;
  }

  public void set_mem_on_heap(double mem_on_heap) {
    this.mem_on_heap = mem_on_heap;
    set_mem_on_heap_isSet(true);
  }

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

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

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

  public double get_mem_off_heap() {
    return this.mem_off_heap;
  }

  public void set_mem_off_heap(double mem_off_heap) {
    this.mem_off_heap = mem_off_heap;
    set_mem_off_heap_isSet(true);
  }

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

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

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

  public double get_cpu() {
    return this.cpu;
  }

  public void set_cpu(double cpu) {
    this.cpu = cpu;
    set_cpu_isSet(true);
  }

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

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

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

  public double get_shared_mem_on_heap() {
    return this.shared_mem_on_heap;
  }

  public void set_shared_mem_on_heap(double shared_mem_on_heap) {
    this.shared_mem_on_heap = shared_mem_on_heap;
    set_shared_mem_on_heap_isSet(true);
  }

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

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

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

  public double get_shared_mem_off_heap() {
    return this.shared_mem_off_heap;
  }

  public void set_shared_mem_off_heap(double shared_mem_off_heap) {
    this.shared_mem_off_heap = shared_mem_off_heap;
    set_shared_mem_off_heap_isSet(true);
  }

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

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

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

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

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

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

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

  public void unset_resources() {
    this.resources = null;
  }

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

  public void set_resources_isSet(boolean value) {
    if (!value) {
      this.resources = null;
    }
  }

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

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

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

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

  public void unset_shared_resources() {
    this.shared_resources = null;
  }

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

  public void set_shared_resources_isSet(boolean value) {
    if (!value) {
      this.shared_resources = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case MEM_ON_HEAP:
      if (value == null) {
        unset_mem_on_heap();
      } else {
        set_mem_on_heap((java.lang.Double)value);
      }
      break;

    case MEM_OFF_HEAP:
      if (value == null) {
        unset_mem_off_heap();
      } else {
        set_mem_off_heap((java.lang.Double)value);
      }
      break;

    case CPU:
      if (value == null) {
        unset_cpu();
      } else {
        set_cpu((java.lang.Double)value);
      }
      break;

    case SHARED_MEM_ON_HEAP:
      if (value == null) {
        unset_shared_mem_on_heap();
      } else {
        set_shared_mem_on_heap((java.lang.Double)value);
      }
      break;

    case SHARED_MEM_OFF_HEAP:
      if (value == null) {
        unset_shared_mem_off_heap();
      } else {
        set_shared_mem_off_heap((java.lang.Double)value);
      }
      break;

    case RESOURCES:
      if (value == null) {
        unset_resources();
      } else {
        set_resources((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

    case SHARED_RESOURCES:
      if (value == null) {
        unset_shared_resources();
      } else {
        set_shared_resources((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

    }
  }

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

    case MEM_OFF_HEAP:
      return get_mem_off_heap();

    case CPU:
      return get_cpu();

    case SHARED_MEM_ON_HEAP:
      return get_shared_mem_on_heap();

    case SHARED_MEM_OFF_HEAP:
      return get_shared_mem_off_heap();

    case RESOURCES:
      return get_resources();

    case SHARED_RESOURCES:
      return get_shared_resources();

    }
    throw new java.lang.IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new java.lang.IllegalArgumentException();
    }

    switch (field) {
    case MEM_ON_HEAP:
      return is_set_mem_on_heap();
    case MEM_OFF_HEAP:
      return is_set_mem_off_heap();
    case CPU:
      return is_set_cpu();
    case SHARED_MEM_ON_HEAP:
      return is_set_shared_mem_on_heap();
    case SHARED_MEM_OFF_HEAP:
      return is_set_shared_mem_off_heap();
    case RESOURCES:
      return is_set_resources();
    case SHARED_RESOURCES:
      return is_set_shared_resources();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_mem_on_heap = true && this.is_set_mem_on_heap();
    boolean that_present_mem_on_heap = true && that.is_set_mem_on_heap();
    if (this_present_mem_on_heap || that_present_mem_on_heap) {
      if (!(this_present_mem_on_heap && that_present_mem_on_heap))
        return false;
      if (this.mem_on_heap != that.mem_on_heap)
        return false;
    }

    boolean this_present_mem_off_heap = true && this.is_set_mem_off_heap();
    boolean that_present_mem_off_heap = true && that.is_set_mem_off_heap();
    if (this_present_mem_off_heap || that_present_mem_off_heap) {
      if (!(this_present_mem_off_heap && that_present_mem_off_heap))
        return false;
      if (this.mem_off_heap != that.mem_off_heap)
        return false;
    }

    boolean this_present_cpu = true && this.is_set_cpu();
    boolean that_present_cpu = true && that.is_set_cpu();
    if (this_present_cpu || that_present_cpu) {
      if (!(this_present_cpu && that_present_cpu))
        return false;
      if (this.cpu != that.cpu)
        return false;
    }

    boolean this_present_shared_mem_on_heap = true && this.is_set_shared_mem_on_heap();
    boolean that_present_shared_mem_on_heap = true && that.is_set_shared_mem_on_heap();
    if (this_present_shared_mem_on_heap || that_present_shared_mem_on_heap) {
      if (!(this_present_shared_mem_on_heap && that_present_shared_mem_on_heap))
        return false;
      if (this.shared_mem_on_heap != that.shared_mem_on_heap)
        return false;
    }

    boolean this_present_shared_mem_off_heap = true && this.is_set_shared_mem_off_heap();
    boolean that_present_shared_mem_off_heap = true && that.is_set_shared_mem_off_heap();
    if (this_present_shared_mem_off_heap || that_present_shared_mem_off_heap) {
      if (!(this_present_shared_mem_off_heap && that_present_shared_mem_off_heap))
        return false;
      if (this.shared_mem_off_heap != that.shared_mem_off_heap)
        return false;
    }

    boolean this_present_resources = true && this.is_set_resources();
    boolean that_present_resources = true && that.is_set_resources();
    if (this_present_resources || that_present_resources) {
      if (!(this_present_resources && that_present_resources))
        return false;
      if (!this.resources.equals(that.resources))
        return false;
    }

    boolean this_present_shared_resources = true && this.is_set_shared_resources();
    boolean that_present_shared_resources = true && that.is_set_shared_resources();
    if (this_present_shared_resources || that_present_shared_resources) {
      if (!(this_present_shared_resources && that_present_shared_resources))
        return false;
      if (!this.shared_resources.equals(that.shared_resources))
        return false;
    }

    return true;
  }

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

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

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

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

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

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

    hashCode = hashCode * 8191 + ((is_set_resources()) ? 131071 : 524287);
    if (is_set_resources())
      hashCode = hashCode * 8191 + resources.hashCode();

    hashCode = hashCode * 8191 + ((is_set_shared_resources()) ? 131071 : 524287);
    if (is_set_shared_resources())
      hashCode = hashCode * 8191 + shared_resources.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_mem_on_heap()).compareTo(other.is_set_mem_on_heap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_mem_on_heap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.mem_on_heap, other.mem_on_heap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_mem_off_heap()).compareTo(other.is_set_mem_off_heap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_mem_off_heap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.mem_off_heap, other.mem_off_heap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_cpu()).compareTo(other.is_set_cpu());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_cpu()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.cpu, other.cpu);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_shared_mem_on_heap()).compareTo(other.is_set_shared_mem_on_heap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_shared_mem_on_heap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.shared_mem_on_heap, other.shared_mem_on_heap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_shared_mem_off_heap()).compareTo(other.is_set_shared_mem_off_heap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_shared_mem_off_heap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.shared_mem_off_heap, other.shared_mem_off_heap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_resources()).compareTo(other.is_set_resources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_resources()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.resources, other.resources);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_shared_resources()).compareTo(other.is_set_shared_resources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_shared_resources()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.shared_resources, other.shared_resources);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    if (is_set_mem_on_heap()) {
      sb.append("mem_on_heap:");
      sb.append(this.mem_on_heap);
      first = false;
    }
    if (is_set_mem_off_heap()) {
      if (!first) sb.append(", ");
      sb.append("mem_off_heap:");
      sb.append(this.mem_off_heap);
      first = false;
    }
    if (is_set_cpu()) {
      if (!first) sb.append(", ");
      sb.append("cpu:");
      sb.append(this.cpu);
      first = false;
    }
    if (is_set_shared_mem_on_heap()) {
      if (!first) sb.append(", ");
      sb.append("shared_mem_on_heap:");
      sb.append(this.shared_mem_on_heap);
      first = false;
    }
    if (is_set_shared_mem_off_heap()) {
      if (!first) sb.append(", ");
      sb.append("shared_mem_off_heap:");
      sb.append(this.shared_mem_off_heap);
      first = false;
    }
    if (is_set_resources()) {
      if (!first) sb.append(", ");
      sb.append("resources:");
      if (this.resources == null) {
        sb.append("null");
      } else {
        sb.append(this.resources);
      }
      first = false;
    }
    if (is_set_shared_resources()) {
      if (!first) sb.append(", ");
      sb.append("shared_resources:");
      if (this.shared_resources == null) {
        sb.append("null");
      } else {
        sb.append(this.shared_resources);
      }
      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 WorkerResourcesStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public WorkerResourcesStandardScheme getScheme() {
      return new WorkerResourcesStandardScheme();
    }
  }

  private static class WorkerResourcesStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<WorkerResources> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, WorkerResources 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: // MEM_ON_HEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.mem_on_heap = iprot.readDouble();
              struct.set_mem_on_heap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // MEM_OFF_HEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.mem_off_heap = iprot.readDouble();
              struct.set_mem_off_heap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // CPU
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.cpu = iprot.readDouble();
              struct.set_cpu_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // SHARED_MEM_ON_HEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.shared_mem_on_heap = iprot.readDouble();
              struct.set_shared_mem_on_heap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // SHARED_MEM_OFF_HEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.DOUBLE) {
              struct.shared_mem_off_heap = iprot.readDouble();
              struct.set_shared_mem_off_heap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // RESOURCES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map716 = iprot.readMapBegin();
                struct.resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map716.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key717;
                double _val718;
                for (int _i719 = 0; _i719 < _map716.size; ++_i719)
                {
                  _key717 = iprot.readString();
                  _val718 = iprot.readDouble();
                  struct.resources.put(_key717, _val718);
                }
                iprot.readMapEnd();
              }
              struct.set_resources_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // SHARED_RESOURCES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map720 = iprot.readMapBegin();
                struct.shared_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map720.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key721;
                double _val722;
                for (int _i723 = 0; _i723 < _map720.size; ++_i723)
                {
                  _key721 = iprot.readString();
                  _val722 = iprot.readDouble();
                  struct.shared_resources.put(_key721, _val722);
                }
                iprot.readMapEnd();
              }
              struct.set_shared_resources_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.is_set_mem_on_heap()) {
        oprot.writeFieldBegin(MEM_ON_HEAP_FIELD_DESC);
        oprot.writeDouble(struct.mem_on_heap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_mem_off_heap()) {
        oprot.writeFieldBegin(MEM_OFF_HEAP_FIELD_DESC);
        oprot.writeDouble(struct.mem_off_heap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_cpu()) {
        oprot.writeFieldBegin(CPU_FIELD_DESC);
        oprot.writeDouble(struct.cpu);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_shared_mem_on_heap()) {
        oprot.writeFieldBegin(SHARED_MEM_ON_HEAP_FIELD_DESC);
        oprot.writeDouble(struct.shared_mem_on_heap);
        oprot.writeFieldEnd();
      }
      if (struct.is_set_shared_mem_off_heap()) {
        oprot.writeFieldBegin(SHARED_MEM_OFF_HEAP_FIELD_DESC);
        oprot.writeDouble(struct.shared_mem_off_heap);
        oprot.writeFieldEnd();
      }
      if (struct.resources != null) {
        if (struct.is_set_resources()) {
          oprot.writeFieldBegin(RESOURCES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.resources.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter724 : struct.resources.entrySet())
            {
              oprot.writeString(_iter724.getKey());
              oprot.writeDouble(_iter724.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.shared_resources != null) {
        if (struct.is_set_shared_resources()) {
          oprot.writeFieldBegin(SHARED_RESOURCES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.shared_resources.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter725 : struct.shared_resources.entrySet())
            {
              oprot.writeString(_iter725.getKey());
              oprot.writeDouble(_iter725.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class WorkerResourcesTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<WorkerResources> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, WorkerResources 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_mem_on_heap()) {
        optionals.set(0);
      }
      if (struct.is_set_mem_off_heap()) {
        optionals.set(1);
      }
      if (struct.is_set_cpu()) {
        optionals.set(2);
      }
      if (struct.is_set_shared_mem_on_heap()) {
        optionals.set(3);
      }
      if (struct.is_set_shared_mem_off_heap()) {
        optionals.set(4);
      }
      if (struct.is_set_resources()) {
        optionals.set(5);
      }
      if (struct.is_set_shared_resources()) {
        optionals.set(6);
      }
      oprot.writeBitSet(optionals, 7);
      if (struct.is_set_mem_on_heap()) {
        oprot.writeDouble(struct.mem_on_heap);
      }
      if (struct.is_set_mem_off_heap()) {
        oprot.writeDouble(struct.mem_off_heap);
      }
      if (struct.is_set_cpu()) {
        oprot.writeDouble(struct.cpu);
      }
      if (struct.is_set_shared_mem_on_heap()) {
        oprot.writeDouble(struct.shared_mem_on_heap);
      }
      if (struct.is_set_shared_mem_off_heap()) {
        oprot.writeDouble(struct.shared_mem_off_heap);
      }
      if (struct.is_set_resources()) {
        {
          oprot.writeI32(struct.resources.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter726 : struct.resources.entrySet())
          {
            oprot.writeString(_iter726.getKey());
            oprot.writeDouble(_iter726.getValue());
          }
        }
      }
      if (struct.is_set_shared_resources()) {
        {
          oprot.writeI32(struct.shared_resources.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter727 : struct.shared_resources.entrySet())
          {
            oprot.writeString(_iter727.getKey());
            oprot.writeDouble(_iter727.getValue());
          }
        }
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, WorkerResources 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(7);
      if (incoming.get(0)) {
        struct.mem_on_heap = iprot.readDouble();
        struct.set_mem_on_heap_isSet(true);
      }
      if (incoming.get(1)) {
        struct.mem_off_heap = iprot.readDouble();
        struct.set_mem_off_heap_isSet(true);
      }
      if (incoming.get(2)) {
        struct.cpu = iprot.readDouble();
        struct.set_cpu_isSet(true);
      }
      if (incoming.get(3)) {
        struct.shared_mem_on_heap = iprot.readDouble();
        struct.set_shared_mem_on_heap_isSet(true);
      }
      if (incoming.get(4)) {
        struct.shared_mem_off_heap = iprot.readDouble();
        struct.set_shared_mem_off_heap_isSet(true);
      }
      if (incoming.get(5)) {
        {
          org.apache.storm.thrift.protocol.TMap _map728 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map728.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key729;
          double _val730;
          for (int _i731 = 0; _i731 < _map728.size; ++_i731)
          {
            _key729 = iprot.readString();
            _val730 = iprot.readDouble();
            struct.resources.put(_key729, _val730);
          }
        }
        struct.set_resources_isSet(true);
      }
      if (incoming.get(6)) {
        {
          org.apache.storm.thrift.protocol.TMap _map732 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.shared_resources = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map732.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key733;
          double _val734;
          for (int _i735 = 0; _i735 < _map732.size; ++_i735)
          {
            _key733 = iprot.readString();
            _val734 = iprot.readDouble();
            struct.shared_resources.put(_key733, _val734);
          }
        }
        struct.set_shared_resources_isSet(true);
      }
    }
  }

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

