/**
 * 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.9.2)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.scheduling;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
/**
 * ComputationalResourceSchedulingModel:
 * 
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2015-11-16")
public class ComputationalResourceSchedulingModel implements org.apache.thrift.TBase<ComputationalResourceSchedulingModel, ComputationalResourceSchedulingModel._Fields>, java.io.Serializable, Cloneable, Comparable<ComputationalResourceSchedulingModel> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ComputationalResourceSchedulingModel");

  private static final org.apache.thrift.protocol.TField RESOURCE_HOST_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("resourceHostId", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField TOTAL_CPUCOUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("totalCPUCount", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField NODE_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("nodeCount", org.apache.thrift.protocol.TType.I32, (short)3);
  private static final org.apache.thrift.protocol.TField NUMBER_OF_THREADS_FIELD_DESC = new org.apache.thrift.protocol.TField("numberOfThreads", org.apache.thrift.protocol.TType.I32, (short)4);
  private static final org.apache.thrift.protocol.TField QUEUE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("queueName", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField WALL_TIME_LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("wallTimeLimit", org.apache.thrift.protocol.TType.I32, (short)6);
  private static final org.apache.thrift.protocol.TField TOTAL_PHYSICAL_MEMORY_FIELD_DESC = new org.apache.thrift.protocol.TField("totalPhysicalMemory", org.apache.thrift.protocol.TType.I32, (short)7);
  private static final org.apache.thrift.protocol.TField CHESSIS_NUMBER_FIELD_DESC = new org.apache.thrift.protocol.TField("chessisNumber", org.apache.thrift.protocol.TType.STRING, (short)8);
  private static final org.apache.thrift.protocol.TField STATIC_WORKING_DIR_FIELD_DESC = new org.apache.thrift.protocol.TField("staticWorkingDir", org.apache.thrift.protocol.TType.STRING, (short)9);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new ComputationalResourceSchedulingModelStandardSchemeFactory());
    schemes.put(TupleScheme.class, new ComputationalResourceSchedulingModelTupleSchemeFactory());
  }

  private String resourceHostId; // optional
  private int totalCPUCount; // optional
  private int nodeCount; // optional
  private int numberOfThreads; // optional
  private String queueName; // optional
  private int wallTimeLimit; // optional
  private int totalPhysicalMemory; // optional
  private String chessisNumber; // optional
  private String staticWorkingDir; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    RESOURCE_HOST_ID((short)1, "resourceHostId"),
    TOTAL_CPUCOUNT((short)2, "totalCPUCount"),
    NODE_COUNT((short)3, "nodeCount"),
    NUMBER_OF_THREADS((short)4, "numberOfThreads"),
    QUEUE_NAME((short)5, "queueName"),
    WALL_TIME_LIMIT((short)6, "wallTimeLimit"),
    TOTAL_PHYSICAL_MEMORY((short)7, "totalPhysicalMemory"),
    CHESSIS_NUMBER((short)8, "chessisNumber"),
    STATIC_WORKING_DIR((short)9, "staticWorkingDir");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // RESOURCE_HOST_ID
          return RESOURCE_HOST_ID;
        case 2: // TOTAL_CPUCOUNT
          return TOTAL_CPUCOUNT;
        case 3: // NODE_COUNT
          return NODE_COUNT;
        case 4: // NUMBER_OF_THREADS
          return NUMBER_OF_THREADS;
        case 5: // QUEUE_NAME
          return QUEUE_NAME;
        case 6: // WALL_TIME_LIMIT
          return WALL_TIME_LIMIT;
        case 7: // TOTAL_PHYSICAL_MEMORY
          return TOTAL_PHYSICAL_MEMORY;
        case 8: // CHESSIS_NUMBER
          return CHESSIS_NUMBER;
        case 9: // STATIC_WORKING_DIR
          return STATIC_WORKING_DIR;
        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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

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

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __TOTALCPUCOUNT_ISSET_ID = 0;
  private static final int __NODECOUNT_ISSET_ID = 1;
  private static final int __NUMBEROFTHREADS_ISSET_ID = 2;
  private static final int __WALLTIMELIMIT_ISSET_ID = 3;
  private static final int __TOTALPHYSICALMEMORY_ISSET_ID = 4;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.RESOURCE_HOST_ID,_Fields.TOTAL_CPUCOUNT,_Fields.NODE_COUNT,_Fields.NUMBER_OF_THREADS,_Fields.QUEUE_NAME,_Fields.WALL_TIME_LIMIT,_Fields.TOTAL_PHYSICAL_MEMORY,_Fields.CHESSIS_NUMBER,_Fields.STATIC_WORKING_DIR};
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.RESOURCE_HOST_ID, new org.apache.thrift.meta_data.FieldMetaData("resourceHostId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TOTAL_CPUCOUNT, new org.apache.thrift.meta_data.FieldMetaData("totalCPUCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NODE_COUNT, new org.apache.thrift.meta_data.FieldMetaData("nodeCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.NUMBER_OF_THREADS, new org.apache.thrift.meta_data.FieldMetaData("numberOfThreads", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.QUEUE_NAME, new org.apache.thrift.meta_data.FieldMetaData("queueName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.WALL_TIME_LIMIT, new org.apache.thrift.meta_data.FieldMetaData("wallTimeLimit", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.TOTAL_PHYSICAL_MEMORY, new org.apache.thrift.meta_data.FieldMetaData("totalPhysicalMemory", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.CHESSIS_NUMBER, new org.apache.thrift.meta_data.FieldMetaData("chessisNumber", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.STATIC_WORKING_DIR, new org.apache.thrift.meta_data.FieldMetaData("staticWorkingDir", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ComputationalResourceSchedulingModel.class, metaDataMap);
  }

  public ComputationalResourceSchedulingModel() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public ComputationalResourceSchedulingModel(ComputationalResourceSchedulingModel other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetResourceHostId()) {
      this.resourceHostId = other.resourceHostId;
    }
    this.totalCPUCount = other.totalCPUCount;
    this.nodeCount = other.nodeCount;
    this.numberOfThreads = other.numberOfThreads;
    if (other.isSetQueueName()) {
      this.queueName = other.queueName;
    }
    this.wallTimeLimit = other.wallTimeLimit;
    this.totalPhysicalMemory = other.totalPhysicalMemory;
    if (other.isSetChessisNumber()) {
      this.chessisNumber = other.chessisNumber;
    }
    if (other.isSetStaticWorkingDir()) {
      this.staticWorkingDir = other.staticWorkingDir;
    }
  }

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

  @Override
  public void clear() {
    this.resourceHostId = null;
    setTotalCPUCountIsSet(false);
    this.totalCPUCount = 0;
    setNodeCountIsSet(false);
    this.nodeCount = 0;
    setNumberOfThreadsIsSet(false);
    this.numberOfThreads = 0;
    this.queueName = null;
    setWallTimeLimitIsSet(false);
    this.wallTimeLimit = 0;
    setTotalPhysicalMemoryIsSet(false);
    this.totalPhysicalMemory = 0;
    this.chessisNumber = null;
    this.staticWorkingDir = null;
  }

  public String getResourceHostId() {
    return this.resourceHostId;
  }

  public void setResourceHostId(String resourceHostId) {
    this.resourceHostId = resourceHostId;
  }

  public void unsetResourceHostId() {
    this.resourceHostId = null;
  }

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

  public void setResourceHostIdIsSet(boolean value) {
    if (!value) {
      this.resourceHostId = null;
    }
  }

  public int getTotalCPUCount() {
    return this.totalCPUCount;
  }

  public void setTotalCPUCount(int totalCPUCount) {
    this.totalCPUCount = totalCPUCount;
    setTotalCPUCountIsSet(true);
  }

  public void unsetTotalCPUCount() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TOTALCPUCOUNT_ISSET_ID);
  }

  /** Returns true if field totalCPUCount is set (has been assigned a value) and false otherwise */
  public boolean isSetTotalCPUCount() {
    return EncodingUtils.testBit(__isset_bitfield, __TOTALCPUCOUNT_ISSET_ID);
  }

  public void setTotalCPUCountIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TOTALCPUCOUNT_ISSET_ID, value);
  }

  public int getNodeCount() {
    return this.nodeCount;
  }

  public void setNodeCount(int nodeCount) {
    this.nodeCount = nodeCount;
    setNodeCountIsSet(true);
  }

  public void unsetNodeCount() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NODECOUNT_ISSET_ID);
  }

  /** Returns true if field nodeCount is set (has been assigned a value) and false otherwise */
  public boolean isSetNodeCount() {
    return EncodingUtils.testBit(__isset_bitfield, __NODECOUNT_ISSET_ID);
  }

  public void setNodeCountIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NODECOUNT_ISSET_ID, value);
  }

  public int getNumberOfThreads() {
    return this.numberOfThreads;
  }

  public void setNumberOfThreads(int numberOfThreads) {
    this.numberOfThreads = numberOfThreads;
    setNumberOfThreadsIsSet(true);
  }

  public void unsetNumberOfThreads() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NUMBEROFTHREADS_ISSET_ID);
  }

  /** Returns true if field numberOfThreads is set (has been assigned a value) and false otherwise */
  public boolean isSetNumberOfThreads() {
    return EncodingUtils.testBit(__isset_bitfield, __NUMBEROFTHREADS_ISSET_ID);
  }

  public void setNumberOfThreadsIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NUMBEROFTHREADS_ISSET_ID, value);
  }

  public String getQueueName() {
    return this.queueName;
  }

  public void setQueueName(String queueName) {
    this.queueName = queueName;
  }

  public void unsetQueueName() {
    this.queueName = null;
  }

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

  public void setQueueNameIsSet(boolean value) {
    if (!value) {
      this.queueName = null;
    }
  }

  public int getWallTimeLimit() {
    return this.wallTimeLimit;
  }

  public void setWallTimeLimit(int wallTimeLimit) {
    this.wallTimeLimit = wallTimeLimit;
    setWallTimeLimitIsSet(true);
  }

  public void unsetWallTimeLimit() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __WALLTIMELIMIT_ISSET_ID);
  }

  /** Returns true if field wallTimeLimit is set (has been assigned a value) and false otherwise */
  public boolean isSetWallTimeLimit() {
    return EncodingUtils.testBit(__isset_bitfield, __WALLTIMELIMIT_ISSET_ID);
  }

  public void setWallTimeLimitIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __WALLTIMELIMIT_ISSET_ID, value);
  }

  public int getTotalPhysicalMemory() {
    return this.totalPhysicalMemory;
  }

  public void setTotalPhysicalMemory(int totalPhysicalMemory) {
    this.totalPhysicalMemory = totalPhysicalMemory;
    setTotalPhysicalMemoryIsSet(true);
  }

  public void unsetTotalPhysicalMemory() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __TOTALPHYSICALMEMORY_ISSET_ID);
  }

  /** Returns true if field totalPhysicalMemory is set (has been assigned a value) and false otherwise */
  public boolean isSetTotalPhysicalMemory() {
    return EncodingUtils.testBit(__isset_bitfield, __TOTALPHYSICALMEMORY_ISSET_ID);
  }

  public void setTotalPhysicalMemoryIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __TOTALPHYSICALMEMORY_ISSET_ID, value);
  }

  public String getChessisNumber() {
    return this.chessisNumber;
  }

  public void setChessisNumber(String chessisNumber) {
    this.chessisNumber = chessisNumber;
  }

  public void unsetChessisNumber() {
    this.chessisNumber = null;
  }

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

  public void setChessisNumberIsSet(boolean value) {
    if (!value) {
      this.chessisNumber = null;
    }
  }

  public String getStaticWorkingDir() {
    return this.staticWorkingDir;
  }

  public void setStaticWorkingDir(String staticWorkingDir) {
    this.staticWorkingDir = staticWorkingDir;
  }

  public void unsetStaticWorkingDir() {
    this.staticWorkingDir = null;
  }

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

  public void setStaticWorkingDirIsSet(boolean value) {
    if (!value) {
      this.staticWorkingDir = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case RESOURCE_HOST_ID:
      if (value == null) {
        unsetResourceHostId();
      } else {
        setResourceHostId((String)value);
      }
      break;

    case TOTAL_CPUCOUNT:
      if (value == null) {
        unsetTotalCPUCount();
      } else {
        setTotalCPUCount((Integer)value);
      }
      break;

    case NODE_COUNT:
      if (value == null) {
        unsetNodeCount();
      } else {
        setNodeCount((Integer)value);
      }
      break;

    case NUMBER_OF_THREADS:
      if (value == null) {
        unsetNumberOfThreads();
      } else {
        setNumberOfThreads((Integer)value);
      }
      break;

    case QUEUE_NAME:
      if (value == null) {
        unsetQueueName();
      } else {
        setQueueName((String)value);
      }
      break;

    case WALL_TIME_LIMIT:
      if (value == null) {
        unsetWallTimeLimit();
      } else {
        setWallTimeLimit((Integer)value);
      }
      break;

    case TOTAL_PHYSICAL_MEMORY:
      if (value == null) {
        unsetTotalPhysicalMemory();
      } else {
        setTotalPhysicalMemory((Integer)value);
      }
      break;

    case CHESSIS_NUMBER:
      if (value == null) {
        unsetChessisNumber();
      } else {
        setChessisNumber((String)value);
      }
      break;

    case STATIC_WORKING_DIR:
      if (value == null) {
        unsetStaticWorkingDir();
      } else {
        setStaticWorkingDir((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case RESOURCE_HOST_ID:
      return getResourceHostId();

    case TOTAL_CPUCOUNT:
      return Integer.valueOf(getTotalCPUCount());

    case NODE_COUNT:
      return Integer.valueOf(getNodeCount());

    case NUMBER_OF_THREADS:
      return Integer.valueOf(getNumberOfThreads());

    case QUEUE_NAME:
      return getQueueName();

    case WALL_TIME_LIMIT:
      return Integer.valueOf(getWallTimeLimit());

    case TOTAL_PHYSICAL_MEMORY:
      return Integer.valueOf(getTotalPhysicalMemory());

    case CHESSIS_NUMBER:
      return getChessisNumber();

    case STATIC_WORKING_DIR:
      return getStaticWorkingDir();

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

    switch (field) {
    case RESOURCE_HOST_ID:
      return isSetResourceHostId();
    case TOTAL_CPUCOUNT:
      return isSetTotalCPUCount();
    case NODE_COUNT:
      return isSetNodeCount();
    case NUMBER_OF_THREADS:
      return isSetNumberOfThreads();
    case QUEUE_NAME:
      return isSetQueueName();
    case WALL_TIME_LIMIT:
      return isSetWallTimeLimit();
    case TOTAL_PHYSICAL_MEMORY:
      return isSetTotalPhysicalMemory();
    case CHESSIS_NUMBER:
      return isSetChessisNumber();
    case STATIC_WORKING_DIR:
      return isSetStaticWorkingDir();
    }
    throw new IllegalStateException();
  }

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

  public boolean equals(ComputationalResourceSchedulingModel that) {
    if (that == null)
      return false;

    boolean this_present_resourceHostId = true && this.isSetResourceHostId();
    boolean that_present_resourceHostId = true && that.isSetResourceHostId();
    if (this_present_resourceHostId || that_present_resourceHostId) {
      if (!(this_present_resourceHostId && that_present_resourceHostId))
        return false;
      if (!this.resourceHostId.equals(that.resourceHostId))
        return false;
    }

    boolean this_present_totalCPUCount = true && this.isSetTotalCPUCount();
    boolean that_present_totalCPUCount = true && that.isSetTotalCPUCount();
    if (this_present_totalCPUCount || that_present_totalCPUCount) {
      if (!(this_present_totalCPUCount && that_present_totalCPUCount))
        return false;
      if (this.totalCPUCount != that.totalCPUCount)
        return false;
    }

    boolean this_present_nodeCount = true && this.isSetNodeCount();
    boolean that_present_nodeCount = true && that.isSetNodeCount();
    if (this_present_nodeCount || that_present_nodeCount) {
      if (!(this_present_nodeCount && that_present_nodeCount))
        return false;
      if (this.nodeCount != that.nodeCount)
        return false;
    }

    boolean this_present_numberOfThreads = true && this.isSetNumberOfThreads();
    boolean that_present_numberOfThreads = true && that.isSetNumberOfThreads();
    if (this_present_numberOfThreads || that_present_numberOfThreads) {
      if (!(this_present_numberOfThreads && that_present_numberOfThreads))
        return false;
      if (this.numberOfThreads != that.numberOfThreads)
        return false;
    }

    boolean this_present_queueName = true && this.isSetQueueName();
    boolean that_present_queueName = true && that.isSetQueueName();
    if (this_present_queueName || that_present_queueName) {
      if (!(this_present_queueName && that_present_queueName))
        return false;
      if (!this.queueName.equals(that.queueName))
        return false;
    }

    boolean this_present_wallTimeLimit = true && this.isSetWallTimeLimit();
    boolean that_present_wallTimeLimit = true && that.isSetWallTimeLimit();
    if (this_present_wallTimeLimit || that_present_wallTimeLimit) {
      if (!(this_present_wallTimeLimit && that_present_wallTimeLimit))
        return false;
      if (this.wallTimeLimit != that.wallTimeLimit)
        return false;
    }

    boolean this_present_totalPhysicalMemory = true && this.isSetTotalPhysicalMemory();
    boolean that_present_totalPhysicalMemory = true && that.isSetTotalPhysicalMemory();
    if (this_present_totalPhysicalMemory || that_present_totalPhysicalMemory) {
      if (!(this_present_totalPhysicalMemory && that_present_totalPhysicalMemory))
        return false;
      if (this.totalPhysicalMemory != that.totalPhysicalMemory)
        return false;
    }

    boolean this_present_chessisNumber = true && this.isSetChessisNumber();
    boolean that_present_chessisNumber = true && that.isSetChessisNumber();
    if (this_present_chessisNumber || that_present_chessisNumber) {
      if (!(this_present_chessisNumber && that_present_chessisNumber))
        return false;
      if (!this.chessisNumber.equals(that.chessisNumber))
        return false;
    }

    boolean this_present_staticWorkingDir = true && this.isSetStaticWorkingDir();
    boolean that_present_staticWorkingDir = true && that.isSetStaticWorkingDir();
    if (this_present_staticWorkingDir || that_present_staticWorkingDir) {
      if (!(this_present_staticWorkingDir && that_present_staticWorkingDir))
        return false;
      if (!this.staticWorkingDir.equals(that.staticWorkingDir))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    List<Object> list = new ArrayList<Object>();

    boolean present_resourceHostId = true && (isSetResourceHostId());
    list.add(present_resourceHostId);
    if (present_resourceHostId)
      list.add(resourceHostId);

    boolean present_totalCPUCount = true && (isSetTotalCPUCount());
    list.add(present_totalCPUCount);
    if (present_totalCPUCount)
      list.add(totalCPUCount);

    boolean present_nodeCount = true && (isSetNodeCount());
    list.add(present_nodeCount);
    if (present_nodeCount)
      list.add(nodeCount);

    boolean present_numberOfThreads = true && (isSetNumberOfThreads());
    list.add(present_numberOfThreads);
    if (present_numberOfThreads)
      list.add(numberOfThreads);

    boolean present_queueName = true && (isSetQueueName());
    list.add(present_queueName);
    if (present_queueName)
      list.add(queueName);

    boolean present_wallTimeLimit = true && (isSetWallTimeLimit());
    list.add(present_wallTimeLimit);
    if (present_wallTimeLimit)
      list.add(wallTimeLimit);

    boolean present_totalPhysicalMemory = true && (isSetTotalPhysicalMemory());
    list.add(present_totalPhysicalMemory);
    if (present_totalPhysicalMemory)
      list.add(totalPhysicalMemory);

    boolean present_chessisNumber = true && (isSetChessisNumber());
    list.add(present_chessisNumber);
    if (present_chessisNumber)
      list.add(chessisNumber);

    boolean present_staticWorkingDir = true && (isSetStaticWorkingDir());
    list.add(present_staticWorkingDir);
    if (present_staticWorkingDir)
      list.add(staticWorkingDir);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    lastComparison = Boolean.valueOf(isSetResourceHostId()).compareTo(other.isSetResourceHostId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetResourceHostId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.resourceHostId, other.resourceHostId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTotalCPUCount()).compareTo(other.isSetTotalCPUCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTotalCPUCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.totalCPUCount, other.totalCPUCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetNodeCount()).compareTo(other.isSetNodeCount());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNodeCount()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nodeCount, other.nodeCount);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetNumberOfThreads()).compareTo(other.isSetNumberOfThreads());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNumberOfThreads()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.numberOfThreads, other.numberOfThreads);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetQueueName()).compareTo(other.isSetQueueName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetQueueName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.queueName, other.queueName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetWallTimeLimit()).compareTo(other.isSetWallTimeLimit());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetWallTimeLimit()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.wallTimeLimit, other.wallTimeLimit);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetTotalPhysicalMemory()).compareTo(other.isSetTotalPhysicalMemory());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTotalPhysicalMemory()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.totalPhysicalMemory, other.totalPhysicalMemory);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetChessisNumber()).compareTo(other.isSetChessisNumber());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetChessisNumber()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.chessisNumber, other.chessisNumber);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStaticWorkingDir()).compareTo(other.isSetStaticWorkingDir());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStaticWorkingDir()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.staticWorkingDir, other.staticWorkingDir);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("ComputationalResourceSchedulingModel(");
    boolean first = true;

    if (isSetResourceHostId()) {
      sb.append("resourceHostId:");
      if (this.resourceHostId == null) {
        sb.append("null");
      } else {
        sb.append(this.resourceHostId);
      }
      first = false;
    }
    if (isSetTotalCPUCount()) {
      if (!first) sb.append(", ");
      sb.append("totalCPUCount:");
      sb.append(this.totalCPUCount);
      first = false;
    }
    if (isSetNodeCount()) {
      if (!first) sb.append(", ");
      sb.append("nodeCount:");
      sb.append(this.nodeCount);
      first = false;
    }
    if (isSetNumberOfThreads()) {
      if (!first) sb.append(", ");
      sb.append("numberOfThreads:");
      sb.append(this.numberOfThreads);
      first = false;
    }
    if (isSetQueueName()) {
      if (!first) sb.append(", ");
      sb.append("queueName:");
      if (this.queueName == null) {
        sb.append("null");
      } else {
        sb.append(this.queueName);
      }
      first = false;
    }
    if (isSetWallTimeLimit()) {
      if (!first) sb.append(", ");
      sb.append("wallTimeLimit:");
      sb.append(this.wallTimeLimit);
      first = false;
    }
    if (isSetTotalPhysicalMemory()) {
      if (!first) sb.append(", ");
      sb.append("totalPhysicalMemory:");
      sb.append(this.totalPhysicalMemory);
      first = false;
    }
    if (isSetChessisNumber()) {
      if (!first) sb.append(", ");
      sb.append("chessisNumber:");
      if (this.chessisNumber == null) {
        sb.append("null");
      } else {
        sb.append(this.chessisNumber);
      }
      first = false;
    }
    if (isSetStaticWorkingDir()) {
      if (!first) sb.append(", ");
      sb.append("staticWorkingDir:");
      if (this.staticWorkingDir == null) {
        sb.append("null");
      } else {
        sb.append(this.staticWorkingDir);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, 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.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class ComputationalResourceSchedulingModelStandardSchemeFactory implements SchemeFactory {
    public ComputationalResourceSchedulingModelStandardScheme getScheme() {
      return new ComputationalResourceSchedulingModelStandardScheme();
    }
  }

  private static class ComputationalResourceSchedulingModelStandardScheme extends StandardScheme<ComputationalResourceSchedulingModel> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, ComputationalResourceSchedulingModel struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // RESOURCE_HOST_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.resourceHostId = iprot.readString();
              struct.setResourceHostIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // TOTAL_CPUCOUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.totalCPUCount = iprot.readI32();
              struct.setTotalCPUCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // NODE_COUNT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.nodeCount = iprot.readI32();
              struct.setNodeCountIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // NUMBER_OF_THREADS
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.numberOfThreads = iprot.readI32();
              struct.setNumberOfThreadsIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // QUEUE_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.queueName = iprot.readString();
              struct.setQueueNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // WALL_TIME_LIMIT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.wallTimeLimit = iprot.readI32();
              struct.setWallTimeLimitIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // TOTAL_PHYSICAL_MEMORY
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.totalPhysicalMemory = iprot.readI32();
              struct.setTotalPhysicalMemoryIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 8: // CHESSIS_NUMBER
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.chessisNumber = iprot.readString();
              struct.setChessisNumberIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 9: // STATIC_WORKING_DIR
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.staticWorkingDir = iprot.readString();
              struct.setStaticWorkingDirIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.resourceHostId != null) {
        if (struct.isSetResourceHostId()) {
          oprot.writeFieldBegin(RESOURCE_HOST_ID_FIELD_DESC);
          oprot.writeString(struct.resourceHostId);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetTotalCPUCount()) {
        oprot.writeFieldBegin(TOTAL_CPUCOUNT_FIELD_DESC);
        oprot.writeI32(struct.totalCPUCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetNodeCount()) {
        oprot.writeFieldBegin(NODE_COUNT_FIELD_DESC);
        oprot.writeI32(struct.nodeCount);
        oprot.writeFieldEnd();
      }
      if (struct.isSetNumberOfThreads()) {
        oprot.writeFieldBegin(NUMBER_OF_THREADS_FIELD_DESC);
        oprot.writeI32(struct.numberOfThreads);
        oprot.writeFieldEnd();
      }
      if (struct.queueName != null) {
        if (struct.isSetQueueName()) {
          oprot.writeFieldBegin(QUEUE_NAME_FIELD_DESC);
          oprot.writeString(struct.queueName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetWallTimeLimit()) {
        oprot.writeFieldBegin(WALL_TIME_LIMIT_FIELD_DESC);
        oprot.writeI32(struct.wallTimeLimit);
        oprot.writeFieldEnd();
      }
      if (struct.isSetTotalPhysicalMemory()) {
        oprot.writeFieldBegin(TOTAL_PHYSICAL_MEMORY_FIELD_DESC);
        oprot.writeI32(struct.totalPhysicalMemory);
        oprot.writeFieldEnd();
      }
      if (struct.chessisNumber != null) {
        if (struct.isSetChessisNumber()) {
          oprot.writeFieldBegin(CHESSIS_NUMBER_FIELD_DESC);
          oprot.writeString(struct.chessisNumber);
          oprot.writeFieldEnd();
        }
      }
      if (struct.staticWorkingDir != null) {
        if (struct.isSetStaticWorkingDir()) {
          oprot.writeFieldBegin(STATIC_WORKING_DIR_FIELD_DESC);
          oprot.writeString(struct.staticWorkingDir);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class ComputationalResourceSchedulingModelTupleSchemeFactory implements SchemeFactory {
    public ComputationalResourceSchedulingModelTupleScheme getScheme() {
      return new ComputationalResourceSchedulingModelTupleScheme();
    }
  }

  private static class ComputationalResourceSchedulingModelTupleScheme extends TupleScheme<ComputationalResourceSchedulingModel> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, ComputationalResourceSchedulingModel struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetResourceHostId()) {
        optionals.set(0);
      }
      if (struct.isSetTotalCPUCount()) {
        optionals.set(1);
      }
      if (struct.isSetNodeCount()) {
        optionals.set(2);
      }
      if (struct.isSetNumberOfThreads()) {
        optionals.set(3);
      }
      if (struct.isSetQueueName()) {
        optionals.set(4);
      }
      if (struct.isSetWallTimeLimit()) {
        optionals.set(5);
      }
      if (struct.isSetTotalPhysicalMemory()) {
        optionals.set(6);
      }
      if (struct.isSetChessisNumber()) {
        optionals.set(7);
      }
      if (struct.isSetStaticWorkingDir()) {
        optionals.set(8);
      }
      oprot.writeBitSet(optionals, 9);
      if (struct.isSetResourceHostId()) {
        oprot.writeString(struct.resourceHostId);
      }
      if (struct.isSetTotalCPUCount()) {
        oprot.writeI32(struct.totalCPUCount);
      }
      if (struct.isSetNodeCount()) {
        oprot.writeI32(struct.nodeCount);
      }
      if (struct.isSetNumberOfThreads()) {
        oprot.writeI32(struct.numberOfThreads);
      }
      if (struct.isSetQueueName()) {
        oprot.writeString(struct.queueName);
      }
      if (struct.isSetWallTimeLimit()) {
        oprot.writeI32(struct.wallTimeLimit);
      }
      if (struct.isSetTotalPhysicalMemory()) {
        oprot.writeI32(struct.totalPhysicalMemory);
      }
      if (struct.isSetChessisNumber()) {
        oprot.writeString(struct.chessisNumber);
      }
      if (struct.isSetStaticWorkingDir()) {
        oprot.writeString(struct.staticWorkingDir);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, ComputationalResourceSchedulingModel struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(9);
      if (incoming.get(0)) {
        struct.resourceHostId = iprot.readString();
        struct.setResourceHostIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.totalCPUCount = iprot.readI32();
        struct.setTotalCPUCountIsSet(true);
      }
      if (incoming.get(2)) {
        struct.nodeCount = iprot.readI32();
        struct.setNodeCountIsSet(true);
      }
      if (incoming.get(3)) {
        struct.numberOfThreads = iprot.readI32();
        struct.setNumberOfThreadsIsSet(true);
      }
      if (incoming.get(4)) {
        struct.queueName = iprot.readString();
        struct.setQueueNameIsSet(true);
      }
      if (incoming.get(5)) {
        struct.wallTimeLimit = iprot.readI32();
        struct.setWallTimeLimitIsSet(true);
      }
      if (incoming.get(6)) {
        struct.totalPhysicalMemory = iprot.readI32();
        struct.setTotalPhysicalMemoryIsSet(true);
      }
      if (incoming.get(7)) {
        struct.chessisNumber = iprot.readString();
        struct.setChessisNumberIsSet(true);
      }
      if (incoming.get(8)) {
        struct.staticWorkingDir = iprot.readString();
        struct.setStaticWorkingDirIsSet(true);
      }
    }
  }

}

