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

  private static final org.apache.storm.thrift.protocol.TField MASTER_CODE_DIR_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("master_code_dir", org.apache.storm.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.storm.thrift.protocol.TField NODE_HOST_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("node_host", org.apache.storm.thrift.protocol.TType.MAP, (short)2);
  private static final org.apache.storm.thrift.protocol.TField EXECUTOR_NODE_PORT_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("executor_node_port", org.apache.storm.thrift.protocol.TType.MAP, (short)3);
  private static final org.apache.storm.thrift.protocol.TField EXECUTOR_START_TIME_SECS_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("executor_start_time_secs", org.apache.storm.thrift.protocol.TType.MAP, (short)4);
  private static final org.apache.storm.thrift.protocol.TField WORKER_RESOURCES_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("worker_resources", org.apache.storm.thrift.protocol.TType.MAP, (short)5);
  private static final org.apache.storm.thrift.protocol.TField TOTAL_SHARED_OFF_HEAP_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("total_shared_off_heap", org.apache.storm.thrift.protocol.TType.MAP, (short)6);
  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)7);

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

  private @org.apache.storm.thrift.annotation.Nullable java.lang.String master_code_dir; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> node_host; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.util.List<java.lang.Long>,NodeInfo> executor_node_port; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.util.List<java.lang.Long>,java.lang.Long> executor_start_time_secs; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<NodeInfo,WorkerResources> worker_resources; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.Double> total_shared_off_heap; // optional
  private @org.apache.storm.thrift.annotation.Nullable java.lang.String owner; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.storm.thrift.TFieldIdEnum {
    MASTER_CODE_DIR((short)1, "master_code_dir"),
    NODE_HOST((short)2, "node_host"),
    EXECUTOR_NODE_PORT((short)3, "executor_node_port"),
    EXECUTOR_START_TIME_SECS((short)4, "executor_start_time_secs"),
    WORKER_RESOURCES((short)5, "worker_resources"),
    TOTAL_SHARED_OFF_HEAP((short)6, "total_shared_off_heap"),
    OWNER((short)7, "owner");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.storm.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // MASTER_CODE_DIR
          return MASTER_CODE_DIR;
        case 2: // NODE_HOST
          return NODE_HOST;
        case 3: // EXECUTOR_NODE_PORT
          return EXECUTOR_NODE_PORT;
        case 4: // EXECUTOR_START_TIME_SECS
          return EXECUTOR_START_TIME_SECS;
        case 5: // WORKER_RESOURCES
          return WORKER_RESOURCES;
        case 6: // TOTAL_SHARED_OFF_HEAP
          return TOTAL_SHARED_OFF_HEAP;
        case 7: // OWNER
          return OWNER;
        default:
          return null;
      }
    }

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

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

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final _Fields optionals[] = {_Fields.NODE_HOST,_Fields.EXECUTOR_NODE_PORT,_Fields.EXECUTOR_START_TIME_SECS,_Fields.WORKER_RESOURCES,_Fields.TOTAL_SHARED_OFF_HEAP,_Fields.OWNER};
  public static final java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.storm.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.MASTER_CODE_DIR, new org.apache.storm.thrift.meta_data.FieldMetaData("master_code_dir", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NODE_HOST, new org.apache.storm.thrift.meta_data.FieldMetaData("node_host", 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.STRING))));
    tmpMap.put(_Fields.EXECUTOR_NODE_PORT, new org.apache.storm.thrift.meta_data.FieldMetaData("executor_node_port", 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.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)), 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, NodeInfo.class))));
    tmpMap.put(_Fields.EXECUTOR_START_TIME_SECS, new org.apache.storm.thrift.meta_data.FieldMetaData("executor_start_time_secs", 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.ListMetaData(org.apache.storm.thrift.protocol.TType.LIST, 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)), 
            new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64))));
    tmpMap.put(_Fields.WORKER_RESOURCES, new org.apache.storm.thrift.meta_data.FieldMetaData("worker_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.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, NodeInfo.class), 
            new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, WorkerResources.class))));
    tmpMap.put(_Fields.TOTAL_SHARED_OFF_HEAP, new org.apache.storm.thrift.meta_data.FieldMetaData("total_shared_off_heap", 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.OWNER, new org.apache.storm.thrift.meta_data.FieldMetaData("owner", org.apache.storm.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Assignment.class, metaDataMap);
  }

  public Assignment() {
    this.node_host = new java.util.HashMap<java.lang.String,java.lang.String>();

    this.executor_node_port = new java.util.HashMap<java.util.List<java.lang.Long>,NodeInfo>();

    this.executor_start_time_secs = new java.util.HashMap<java.util.List<java.lang.Long>,java.lang.Long>();

    this.worker_resources = new java.util.HashMap<NodeInfo,WorkerResources>();

    this.total_shared_off_heap = new java.util.HashMap<java.lang.String,java.lang.Double>();

  }

  public Assignment(
    java.lang.String master_code_dir)
  {
    this();
    this.master_code_dir = master_code_dir;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Assignment(Assignment other) {
    if (other.is_set_master_code_dir()) {
      this.master_code_dir = other.master_code_dir;
    }
    if (other.is_set_node_host()) {
      java.util.Map<java.lang.String,java.lang.String> __this__node_host = new java.util.HashMap<java.lang.String,java.lang.String>(other.node_host);
      this.node_host = __this__node_host;
    }
    if (other.is_set_executor_node_port()) {
      java.util.Map<java.util.List<java.lang.Long>,NodeInfo> __this__executor_node_port = new java.util.HashMap<java.util.List<java.lang.Long>,NodeInfo>(other.executor_node_port.size());
      for (java.util.Map.Entry<java.util.List<java.lang.Long>, NodeInfo> other_element : other.executor_node_port.entrySet()) {

        java.util.List<java.lang.Long> other_element_key = other_element.getKey();
        NodeInfo other_element_value = other_element.getValue();

        java.util.List<java.lang.Long> __this__executor_node_port_copy_key = new java.util.ArrayList<java.lang.Long>(other_element_key);

        NodeInfo __this__executor_node_port_copy_value = new NodeInfo(other_element_value);

        __this__executor_node_port.put(__this__executor_node_port_copy_key, __this__executor_node_port_copy_value);
      }
      this.executor_node_port = __this__executor_node_port;
    }
    if (other.is_set_executor_start_time_secs()) {
      java.util.Map<java.util.List<java.lang.Long>,java.lang.Long> __this__executor_start_time_secs = new java.util.HashMap<java.util.List<java.lang.Long>,java.lang.Long>(other.executor_start_time_secs.size());
      for (java.util.Map.Entry<java.util.List<java.lang.Long>, java.lang.Long> other_element : other.executor_start_time_secs.entrySet()) {

        java.util.List<java.lang.Long> other_element_key = other_element.getKey();
        java.lang.Long other_element_value = other_element.getValue();

        java.util.List<java.lang.Long> __this__executor_start_time_secs_copy_key = new java.util.ArrayList<java.lang.Long>(other_element_key);

        java.lang.Long __this__executor_start_time_secs_copy_value = other_element_value;

        __this__executor_start_time_secs.put(__this__executor_start_time_secs_copy_key, __this__executor_start_time_secs_copy_value);
      }
      this.executor_start_time_secs = __this__executor_start_time_secs;
    }
    if (other.is_set_worker_resources()) {
      java.util.Map<NodeInfo,WorkerResources> __this__worker_resources = new java.util.HashMap<NodeInfo,WorkerResources>(other.worker_resources.size());
      for (java.util.Map.Entry<NodeInfo, WorkerResources> other_element : other.worker_resources.entrySet()) {

        NodeInfo other_element_key = other_element.getKey();
        WorkerResources other_element_value = other_element.getValue();

        NodeInfo __this__worker_resources_copy_key = new NodeInfo(other_element_key);

        WorkerResources __this__worker_resources_copy_value = new WorkerResources(other_element_value);

        __this__worker_resources.put(__this__worker_resources_copy_key, __this__worker_resources_copy_value);
      }
      this.worker_resources = __this__worker_resources;
    }
    if (other.is_set_total_shared_off_heap()) {
      java.util.Map<java.lang.String,java.lang.Double> __this__total_shared_off_heap = new java.util.HashMap<java.lang.String,java.lang.Double>(other.total_shared_off_heap);
      this.total_shared_off_heap = __this__total_shared_off_heap;
    }
    if (other.is_set_owner()) {
      this.owner = other.owner;
    }
  }

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

  @Override
  public void clear() {
    this.master_code_dir = null;
    this.node_host = new java.util.HashMap<java.lang.String,java.lang.String>();

    this.executor_node_port = new java.util.HashMap<java.util.List<java.lang.Long>,NodeInfo>();

    this.executor_start_time_secs = new java.util.HashMap<java.util.List<java.lang.Long>,java.lang.Long>();

    this.worker_resources = new java.util.HashMap<NodeInfo,WorkerResources>();

    this.total_shared_off_heap = new java.util.HashMap<java.lang.String,java.lang.Double>();

    this.owner = null;
  }

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

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

  public void unset_master_code_dir() {
    this.master_code_dir = null;
  }

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

  public void set_master_code_dir_isSet(boolean value) {
    if (!value) {
      this.master_code_dir = null;
    }
  }

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

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

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

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

  public void unset_node_host() {
    this.node_host = null;
  }

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

  public void set_node_host_isSet(boolean value) {
    if (!value) {
      this.node_host = null;
    }
  }

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

  public void put_to_executor_node_port(java.util.List<java.lang.Long> key, NodeInfo val) {
    if (this.executor_node_port == null) {
      this.executor_node_port = new java.util.HashMap<java.util.List<java.lang.Long>,NodeInfo>();
    }
    this.executor_node_port.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<java.util.List<java.lang.Long>,NodeInfo> get_executor_node_port() {
    return this.executor_node_port;
  }

  public void set_executor_node_port(@org.apache.storm.thrift.annotation.Nullable java.util.Map<java.util.List<java.lang.Long>,NodeInfo> executor_node_port) {
    this.executor_node_port = executor_node_port;
  }

  public void unset_executor_node_port() {
    this.executor_node_port = null;
  }

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

  public void set_executor_node_port_isSet(boolean value) {
    if (!value) {
      this.executor_node_port = null;
    }
  }

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

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

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

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

  public void unset_executor_start_time_secs() {
    this.executor_start_time_secs = null;
  }

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

  public void set_executor_start_time_secs_isSet(boolean value) {
    if (!value) {
      this.executor_start_time_secs = null;
    }
  }

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

  public void put_to_worker_resources(NodeInfo key, WorkerResources val) {
    if (this.worker_resources == null) {
      this.worker_resources = new java.util.HashMap<NodeInfo,WorkerResources>();
    }
    this.worker_resources.put(key, val);
  }

  @org.apache.storm.thrift.annotation.Nullable
  public java.util.Map<NodeInfo,WorkerResources> get_worker_resources() {
    return this.worker_resources;
  }

  public void set_worker_resources(@org.apache.storm.thrift.annotation.Nullable java.util.Map<NodeInfo,WorkerResources> worker_resources) {
    this.worker_resources = worker_resources;
  }

  public void unset_worker_resources() {
    this.worker_resources = null;
  }

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

  public void set_worker_resources_isSet(boolean value) {
    if (!value) {
      this.worker_resources = null;
    }
  }

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

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

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

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

  public void unset_total_shared_off_heap() {
    this.total_shared_off_heap = null;
  }

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

  public void set_total_shared_off_heap_isSet(boolean value) {
    if (!value) {
      this.total_shared_off_heap = 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 void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case MASTER_CODE_DIR:
      if (value == null) {
        unset_master_code_dir();
      } else {
        set_master_code_dir((java.lang.String)value);
      }
      break;

    case NODE_HOST:
      if (value == null) {
        unset_node_host();
      } else {
        set_node_host((java.util.Map<java.lang.String,java.lang.String>)value);
      }
      break;

    case EXECUTOR_NODE_PORT:
      if (value == null) {
        unset_executor_node_port();
      } else {
        set_executor_node_port((java.util.Map<java.util.List<java.lang.Long>,NodeInfo>)value);
      }
      break;

    case EXECUTOR_START_TIME_SECS:
      if (value == null) {
        unset_executor_start_time_secs();
      } else {
        set_executor_start_time_secs((java.util.Map<java.util.List<java.lang.Long>,java.lang.Long>)value);
      }
      break;

    case WORKER_RESOURCES:
      if (value == null) {
        unset_worker_resources();
      } else {
        set_worker_resources((java.util.Map<NodeInfo,WorkerResources>)value);
      }
      break;

    case TOTAL_SHARED_OFF_HEAP:
      if (value == null) {
        unset_total_shared_off_heap();
      } else {
        set_total_shared_off_heap((java.util.Map<java.lang.String,java.lang.Double>)value);
      }
      break;

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

    }
  }

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

    case NODE_HOST:
      return get_node_host();

    case EXECUTOR_NODE_PORT:
      return get_executor_node_port();

    case EXECUTOR_START_TIME_SECS:
      return get_executor_start_time_secs();

    case WORKER_RESOURCES:
      return get_worker_resources();

    case TOTAL_SHARED_OFF_HEAP:
      return get_total_shared_off_heap();

    case OWNER:
      return get_owner();

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

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

    switch (field) {
    case MASTER_CODE_DIR:
      return is_set_master_code_dir();
    case NODE_HOST:
      return is_set_node_host();
    case EXECUTOR_NODE_PORT:
      return is_set_executor_node_port();
    case EXECUTOR_START_TIME_SECS:
      return is_set_executor_start_time_secs();
    case WORKER_RESOURCES:
      return is_set_worker_resources();
    case TOTAL_SHARED_OFF_HEAP:
      return is_set_total_shared_off_heap();
    case OWNER:
      return is_set_owner();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_master_code_dir = true && this.is_set_master_code_dir();
    boolean that_present_master_code_dir = true && that.is_set_master_code_dir();
    if (this_present_master_code_dir || that_present_master_code_dir) {
      if (!(this_present_master_code_dir && that_present_master_code_dir))
        return false;
      if (!this.master_code_dir.equals(that.master_code_dir))
        return false;
    }

    boolean this_present_node_host = true && this.is_set_node_host();
    boolean that_present_node_host = true && that.is_set_node_host();
    if (this_present_node_host || that_present_node_host) {
      if (!(this_present_node_host && that_present_node_host))
        return false;
      if (!this.node_host.equals(that.node_host))
        return false;
    }

    boolean this_present_executor_node_port = true && this.is_set_executor_node_port();
    boolean that_present_executor_node_port = true && that.is_set_executor_node_port();
    if (this_present_executor_node_port || that_present_executor_node_port) {
      if (!(this_present_executor_node_port && that_present_executor_node_port))
        return false;
      if (!this.executor_node_port.equals(that.executor_node_port))
        return false;
    }

    boolean this_present_executor_start_time_secs = true && this.is_set_executor_start_time_secs();
    boolean that_present_executor_start_time_secs = true && that.is_set_executor_start_time_secs();
    if (this_present_executor_start_time_secs || that_present_executor_start_time_secs) {
      if (!(this_present_executor_start_time_secs && that_present_executor_start_time_secs))
        return false;
      if (!this.executor_start_time_secs.equals(that.executor_start_time_secs))
        return false;
    }

    boolean this_present_worker_resources = true && this.is_set_worker_resources();
    boolean that_present_worker_resources = true && that.is_set_worker_resources();
    if (this_present_worker_resources || that_present_worker_resources) {
      if (!(this_present_worker_resources && that_present_worker_resources))
        return false;
      if (!this.worker_resources.equals(that.worker_resources))
        return false;
    }

    boolean this_present_total_shared_off_heap = true && this.is_set_total_shared_off_heap();
    boolean that_present_total_shared_off_heap = true && that.is_set_total_shared_off_heap();
    if (this_present_total_shared_off_heap || that_present_total_shared_off_heap) {
      if (!(this_present_total_shared_off_heap && that_present_total_shared_off_heap))
        return false;
      if (!this.total_shared_off_heap.equals(that.total_shared_off_heap))
        return false;
    }

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

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_master_code_dir()) ? 131071 : 524287);
    if (is_set_master_code_dir())
      hashCode = hashCode * 8191 + master_code_dir.hashCode();

    hashCode = hashCode * 8191 + ((is_set_node_host()) ? 131071 : 524287);
    if (is_set_node_host())
      hashCode = hashCode * 8191 + node_host.hashCode();

    hashCode = hashCode * 8191 + ((is_set_executor_node_port()) ? 131071 : 524287);
    if (is_set_executor_node_port())
      hashCode = hashCode * 8191 + executor_node_port.hashCode();

    hashCode = hashCode * 8191 + ((is_set_executor_start_time_secs()) ? 131071 : 524287);
    if (is_set_executor_start_time_secs())
      hashCode = hashCode * 8191 + executor_start_time_secs.hashCode();

    hashCode = hashCode * 8191 + ((is_set_worker_resources()) ? 131071 : 524287);
    if (is_set_worker_resources())
      hashCode = hashCode * 8191 + worker_resources.hashCode();

    hashCode = hashCode * 8191 + ((is_set_total_shared_off_heap()) ? 131071 : 524287);
    if (is_set_total_shared_off_heap())
      hashCode = hashCode * 8191 + total_shared_off_heap.hashCode();

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

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_master_code_dir()).compareTo(other.is_set_master_code_dir());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_master_code_dir()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.master_code_dir, other.master_code_dir);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_node_host()).compareTo(other.is_set_node_host());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_node_host()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.node_host, other.node_host);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_executor_node_port()).compareTo(other.is_set_executor_node_port());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_executor_node_port()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.executor_node_port, other.executor_node_port);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_executor_start_time_secs()).compareTo(other.is_set_executor_start_time_secs());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_executor_start_time_secs()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.executor_start_time_secs, other.executor_start_time_secs);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_worker_resources()).compareTo(other.is_set_worker_resources());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_worker_resources()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.worker_resources, other.worker_resources);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_total_shared_off_heap()).compareTo(other.is_set_total_shared_off_heap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_total_shared_off_heap()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.total_shared_off_heap, other.total_shared_off_heap);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_owner()).compareTo(other.is_set_owner());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_owner()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.owner, other.owner);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    sb.append("master_code_dir:");
    if (this.master_code_dir == null) {
      sb.append("null");
    } else {
      sb.append(this.master_code_dir);
    }
    first = false;
    if (is_set_node_host()) {
      if (!first) sb.append(", ");
      sb.append("node_host:");
      if (this.node_host == null) {
        sb.append("null");
      } else {
        sb.append(this.node_host);
      }
      first = false;
    }
    if (is_set_executor_node_port()) {
      if (!first) sb.append(", ");
      sb.append("executor_node_port:");
      if (this.executor_node_port == null) {
        sb.append("null");
      } else {
        sb.append(this.executor_node_port);
      }
      first = false;
    }
    if (is_set_executor_start_time_secs()) {
      if (!first) sb.append(", ");
      sb.append("executor_start_time_secs:");
      if (this.executor_start_time_secs == null) {
        sb.append("null");
      } else {
        sb.append(this.executor_start_time_secs);
      }
      first = false;
    }
    if (is_set_worker_resources()) {
      if (!first) sb.append(", ");
      sb.append("worker_resources:");
      if (this.worker_resources == null) {
        sb.append("null");
      } else {
        sb.append(this.worker_resources);
      }
      first = false;
    }
    if (is_set_total_shared_off_heap()) {
      if (!first) sb.append(", ");
      sb.append("total_shared_off_heap:");
      if (this.total_shared_off_heap == null) {
        sb.append("null");
      } else {
        sb.append(this.total_shared_off_heap);
      }
      first = false;
    }
    if (is_set_owner()) {
      if (!first) sb.append(", ");
      sb.append("owner:");
      if (this.owner == null) {
        sb.append("null");
      } else {
        sb.append(this.owner);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.storm.thrift.TException {
    // check for required fields
    if (!is_set_master_code_dir()) {
      throw new org.apache.storm.thrift.protocol.TProtocolException("Required field 'master_code_dir' 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 {
      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 AssignmentStandardSchemeFactory implements org.apache.storm.thrift.scheme.SchemeFactory {
    public AssignmentStandardScheme getScheme() {
      return new AssignmentStandardScheme();
    }
  }

  private static class AssignmentStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<Assignment> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, Assignment 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: // MASTER_CODE_DIR
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.master_code_dir = iprot.readString();
              struct.set_master_code_dir_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // NODE_HOST
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map736 = iprot.readMapBegin();
                struct.node_host = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map736.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key737;
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _val738;
                for (int _i739 = 0; _i739 < _map736.size; ++_i739)
                {
                  _key737 = iprot.readString();
                  _val738 = iprot.readString();
                  struct.node_host.put(_key737, _val738);
                }
                iprot.readMapEnd();
              }
              struct.set_node_host_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // EXECUTOR_NODE_PORT
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map740 = iprot.readMapBegin();
                struct.executor_node_port = new java.util.HashMap<java.util.List<java.lang.Long>,NodeInfo>(2*_map740.size);
                @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> _key741;
                @org.apache.storm.thrift.annotation.Nullable NodeInfo _val742;
                for (int _i743 = 0; _i743 < _map740.size; ++_i743)
                {
                  {
                    org.apache.storm.thrift.protocol.TList _list744 = iprot.readListBegin();
                    _key741 = new java.util.ArrayList<java.lang.Long>(_list744.size);
                    long _elem745;
                    for (int _i746 = 0; _i746 < _list744.size; ++_i746)
                    {
                      _elem745 = iprot.readI64();
                      _key741.add(_elem745);
                    }
                    iprot.readListEnd();
                  }
                  _val742 = new NodeInfo();
                  _val742.read(iprot);
                  struct.executor_node_port.put(_key741, _val742);
                }
                iprot.readMapEnd();
              }
              struct.set_executor_node_port_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // EXECUTOR_START_TIME_SECS
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map747 = iprot.readMapBegin();
                struct.executor_start_time_secs = new java.util.HashMap<java.util.List<java.lang.Long>,java.lang.Long>(2*_map747.size);
                @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> _key748;
                long _val749;
                for (int _i750 = 0; _i750 < _map747.size; ++_i750)
                {
                  {
                    org.apache.storm.thrift.protocol.TList _list751 = iprot.readListBegin();
                    _key748 = new java.util.ArrayList<java.lang.Long>(_list751.size);
                    long _elem752;
                    for (int _i753 = 0; _i753 < _list751.size; ++_i753)
                    {
                      _elem752 = iprot.readI64();
                      _key748.add(_elem752);
                    }
                    iprot.readListEnd();
                  }
                  _val749 = iprot.readI64();
                  struct.executor_start_time_secs.put(_key748, _val749);
                }
                iprot.readMapEnd();
              }
              struct.set_executor_start_time_secs_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // WORKER_RESOURCES
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map754 = iprot.readMapBegin();
                struct.worker_resources = new java.util.HashMap<NodeInfo,WorkerResources>(2*_map754.size);
                @org.apache.storm.thrift.annotation.Nullable NodeInfo _key755;
                @org.apache.storm.thrift.annotation.Nullable WorkerResources _val756;
                for (int _i757 = 0; _i757 < _map754.size; ++_i757)
                {
                  _key755 = new NodeInfo();
                  _key755.read(iprot);
                  _val756 = new WorkerResources();
                  _val756.read(iprot);
                  struct.worker_resources.put(_key755, _val756);
                }
                iprot.readMapEnd();
              }
              struct.set_worker_resources_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // TOTAL_SHARED_OFF_HEAP
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map758 = iprot.readMapBegin();
                struct.total_shared_off_heap = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map758.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key759;
                double _val760;
                for (int _i761 = 0; _i761 < _map758.size; ++_i761)
                {
                  _key759 = iprot.readString();
                  _val760 = iprot.readDouble();
                  struct.total_shared_off_heap.put(_key759, _val760);
                }
                iprot.readMapEnd();
              }
              struct.set_total_shared_off_heap_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // OWNER
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.STRING) {
              struct.owner = iprot.readString();
              struct.set_owner_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.master_code_dir != null) {
        oprot.writeFieldBegin(MASTER_CODE_DIR_FIELD_DESC);
        oprot.writeString(struct.master_code_dir);
        oprot.writeFieldEnd();
      }
      if (struct.node_host != null) {
        if (struct.is_set_node_host()) {
          oprot.writeFieldBegin(NODE_HOST_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRING, struct.node_host.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter762 : struct.node_host.entrySet())
            {
              oprot.writeString(_iter762.getKey());
              oprot.writeString(_iter762.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.executor_node_port != null) {
        if (struct.is_set_executor_node_port()) {
          oprot.writeFieldBegin(EXECUTOR_NODE_PORT_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.LIST, org.apache.storm.thrift.protocol.TType.STRUCT, struct.executor_node_port.size()));
            for (java.util.Map.Entry<java.util.List<java.lang.Long>, NodeInfo> _iter763 : struct.executor_node_port.entrySet())
            {
              {
                oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, _iter763.getKey().size()));
                for (long _iter764 : _iter763.getKey())
                {
                  oprot.writeI64(_iter764);
                }
                oprot.writeListEnd();
              }
              _iter763.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.executor_start_time_secs != null) {
        if (struct.is_set_executor_start_time_secs()) {
          oprot.writeFieldBegin(EXECUTOR_START_TIME_SECS_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.LIST, org.apache.storm.thrift.protocol.TType.I64, struct.executor_start_time_secs.size()));
            for (java.util.Map.Entry<java.util.List<java.lang.Long>, java.lang.Long> _iter765 : struct.executor_start_time_secs.entrySet())
            {
              {
                oprot.writeListBegin(new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, _iter765.getKey().size()));
                for (long _iter766 : _iter765.getKey())
                {
                  oprot.writeI64(_iter766);
                }
                oprot.writeListEnd();
              }
              oprot.writeI64(_iter765.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.worker_resources != null) {
        if (struct.is_set_worker_resources()) {
          oprot.writeFieldBegin(WORKER_RESOURCES_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.STRUCT, struct.worker_resources.size()));
            for (java.util.Map.Entry<NodeInfo, WorkerResources> _iter767 : struct.worker_resources.entrySet())
            {
              _iter767.getKey().write(oprot);
              _iter767.getValue().write(oprot);
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.total_shared_off_heap != null) {
        if (struct.is_set_total_shared_off_heap()) {
          oprot.writeFieldBegin(TOTAL_SHARED_OFF_HEAP_FIELD_DESC);
          {
            oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, struct.total_shared_off_heap.size()));
            for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter768 : struct.total_shared_off_heap.entrySet())
            {
              oprot.writeString(_iter768.getKey());
              oprot.writeDouble(_iter768.getValue());
            }
            oprot.writeMapEnd();
          }
          oprot.writeFieldEnd();
        }
      }
      if (struct.owner != null) {
        if (struct.is_set_owner()) {
          oprot.writeFieldBegin(OWNER_FIELD_DESC);
          oprot.writeString(struct.owner);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class AssignmentTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<Assignment> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, Assignment struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      oprot.writeString(struct.master_code_dir);
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.is_set_node_host()) {
        optionals.set(0);
      }
      if (struct.is_set_executor_node_port()) {
        optionals.set(1);
      }
      if (struct.is_set_executor_start_time_secs()) {
        optionals.set(2);
      }
      if (struct.is_set_worker_resources()) {
        optionals.set(3);
      }
      if (struct.is_set_total_shared_off_heap()) {
        optionals.set(4);
      }
      if (struct.is_set_owner()) {
        optionals.set(5);
      }
      oprot.writeBitSet(optionals, 6);
      if (struct.is_set_node_host()) {
        {
          oprot.writeI32(struct.node_host.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter769 : struct.node_host.entrySet())
          {
            oprot.writeString(_iter769.getKey());
            oprot.writeString(_iter769.getValue());
          }
        }
      }
      if (struct.is_set_executor_node_port()) {
        {
          oprot.writeI32(struct.executor_node_port.size());
          for (java.util.Map.Entry<java.util.List<java.lang.Long>, NodeInfo> _iter770 : struct.executor_node_port.entrySet())
          {
            {
              oprot.writeI32(_iter770.getKey().size());
              for (long _iter771 : _iter770.getKey())
              {
                oprot.writeI64(_iter771);
              }
            }
            _iter770.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_executor_start_time_secs()) {
        {
          oprot.writeI32(struct.executor_start_time_secs.size());
          for (java.util.Map.Entry<java.util.List<java.lang.Long>, java.lang.Long> _iter772 : struct.executor_start_time_secs.entrySet())
          {
            {
              oprot.writeI32(_iter772.getKey().size());
              for (long _iter773 : _iter772.getKey())
              {
                oprot.writeI64(_iter773);
              }
            }
            oprot.writeI64(_iter772.getValue());
          }
        }
      }
      if (struct.is_set_worker_resources()) {
        {
          oprot.writeI32(struct.worker_resources.size());
          for (java.util.Map.Entry<NodeInfo, WorkerResources> _iter774 : struct.worker_resources.entrySet())
          {
            _iter774.getKey().write(oprot);
            _iter774.getValue().write(oprot);
          }
        }
      }
      if (struct.is_set_total_shared_off_heap()) {
        {
          oprot.writeI32(struct.total_shared_off_heap.size());
          for (java.util.Map.Entry<java.lang.String, java.lang.Double> _iter775 : struct.total_shared_off_heap.entrySet())
          {
            oprot.writeString(_iter775.getKey());
            oprot.writeDouble(_iter775.getValue());
          }
        }
      }
      if (struct.is_set_owner()) {
        oprot.writeString(struct.owner);
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, Assignment struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      struct.master_code_dir = iprot.readString();
      struct.set_master_code_dir_isSet(true);
      java.util.BitSet incoming = iprot.readBitSet(6);
      if (incoming.get(0)) {
        {
          org.apache.storm.thrift.protocol.TMap _map776 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.STRING, iprot.readI32());
          struct.node_host = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map776.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key777;
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _val778;
          for (int _i779 = 0; _i779 < _map776.size; ++_i779)
          {
            _key777 = iprot.readString();
            _val778 = iprot.readString();
            struct.node_host.put(_key777, _val778);
          }
        }
        struct.set_node_host_isSet(true);
      }
      if (incoming.get(1)) {
        {
          org.apache.storm.thrift.protocol.TMap _map780 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.LIST, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.executor_node_port = new java.util.HashMap<java.util.List<java.lang.Long>,NodeInfo>(2*_map780.size);
          @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> _key781;
          @org.apache.storm.thrift.annotation.Nullable NodeInfo _val782;
          for (int _i783 = 0; _i783 < _map780.size; ++_i783)
          {
            {
              org.apache.storm.thrift.protocol.TList _list784 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
              _key781 = new java.util.ArrayList<java.lang.Long>(_list784.size);
              long _elem785;
              for (int _i786 = 0; _i786 < _list784.size; ++_i786)
              {
                _elem785 = iprot.readI64();
                _key781.add(_elem785);
              }
            }
            _val782 = new NodeInfo();
            _val782.read(iprot);
            struct.executor_node_port.put(_key781, _val782);
          }
        }
        struct.set_executor_node_port_isSet(true);
      }
      if (incoming.get(2)) {
        {
          org.apache.storm.thrift.protocol.TMap _map787 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.LIST, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
          struct.executor_start_time_secs = new java.util.HashMap<java.util.List<java.lang.Long>,java.lang.Long>(2*_map787.size);
          @org.apache.storm.thrift.annotation.Nullable java.util.List<java.lang.Long> _key788;
          long _val789;
          for (int _i790 = 0; _i790 < _map787.size; ++_i790)
          {
            {
              org.apache.storm.thrift.protocol.TList _list791 = new org.apache.storm.thrift.protocol.TList(org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
              _key788 = new java.util.ArrayList<java.lang.Long>(_list791.size);
              long _elem792;
              for (int _i793 = 0; _i793 < _list791.size; ++_i793)
              {
                _elem792 = iprot.readI64();
                _key788.add(_elem792);
              }
            }
            _val789 = iprot.readI64();
            struct.executor_start_time_secs.put(_key788, _val789);
          }
        }
        struct.set_executor_start_time_secs_isSet(true);
      }
      if (incoming.get(3)) {
        {
          org.apache.storm.thrift.protocol.TMap _map794 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.worker_resources = new java.util.HashMap<NodeInfo,WorkerResources>(2*_map794.size);
          @org.apache.storm.thrift.annotation.Nullable NodeInfo _key795;
          @org.apache.storm.thrift.annotation.Nullable WorkerResources _val796;
          for (int _i797 = 0; _i797 < _map794.size; ++_i797)
          {
            _key795 = new NodeInfo();
            _key795.read(iprot);
            _val796 = new WorkerResources();
            _val796.read(iprot);
            struct.worker_resources.put(_key795, _val796);
          }
        }
        struct.set_worker_resources_isSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.storm.thrift.protocol.TMap _map798 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
          struct.total_shared_off_heap = new java.util.HashMap<java.lang.String,java.lang.Double>(2*_map798.size);
          @org.apache.storm.thrift.annotation.Nullable java.lang.String _key799;
          double _val800;
          for (int _i801 = 0; _i801 < _map798.size; ++_i801)
          {
            _key799 = iprot.readString();
            _val800 = iprot.readDouble();
            struct.total_shared_off_heap.put(_key799, _val800);
          }
        }
        struct.set_total_shared_off_heap_isSet(true);
      }
      if (incoming.get(5)) {
        struct.owner = iprot.readString();
        struct.set_owner_isSet(true);
      }
    }
  }

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

