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

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

  private static final org.apache.storm.thrift.protocol.TField ACKED_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("acked", org.apache.storm.thrift.protocol.TType.MAP, (short)1);
  private static final org.apache.storm.thrift.protocol.TField FAILED_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("failed", org.apache.storm.thrift.protocol.TType.MAP, (short)2);
  private static final org.apache.storm.thrift.protocol.TField PROCESS_MS_AVG_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("process_ms_avg", org.apache.storm.thrift.protocol.TType.MAP, (short)3);
  private static final org.apache.storm.thrift.protocol.TField EXECUTED_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("executed", org.apache.storm.thrift.protocol.TType.MAP, (short)4);
  private static final org.apache.storm.thrift.protocol.TField EXECUTE_MS_AVG_FIELD_DESC = new org.apache.storm.thrift.protocol.TField("execute_ms_avg", org.apache.storm.thrift.protocol.TType.MAP, (short)5);

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

  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> acked; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> failed; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>> process_ms_avg; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> executed; // required
  private @org.apache.storm.thrift.annotation.Nullable java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>> execute_ms_avg; // required

  /** 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 {
    ACKED((short)1, "acked"),
    FAILED((short)2, "failed"),
    PROCESS_MS_AVG((short)3, "process_ms_avg"),
    EXECUTED((short)4, "executed"),
    EXECUTE_MS_AVG((short)5, "execute_ms_avg");

    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: // ACKED
          return ACKED;
        case 2: // FAILED
          return FAILED;
        case 3: // PROCESS_MS_AVG
          return PROCESS_MS_AVG;
        case 4: // EXECUTED
          return EXECUTED;
        case 5: // EXECUTE_MS_AVG
          return EXECUTE_MS_AVG;
        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
  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.ACKED, new org.apache.storm.thrift.meta_data.FieldMetaData("acked", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
                new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)))));
    tmpMap.put(_Fields.FAILED, new org.apache.storm.thrift.meta_data.FieldMetaData("failed", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
                new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)))));
    tmpMap.put(_Fields.PROCESS_MS_AVG, new org.apache.storm.thrift.meta_data.FieldMetaData("process_ms_avg", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
                new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)))));
    tmpMap.put(_Fields.EXECUTED, new org.apache.storm.thrift.meta_data.FieldMetaData("executed", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
                new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.I64)))));
    tmpMap.put(_Fields.EXECUTE_MS_AVG, new org.apache.storm.thrift.meta_data.FieldMetaData("execute_ms_avg", org.apache.storm.thrift.TFieldRequirementType.REQUIRED, 
        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.MapMetaData(org.apache.storm.thrift.protocol.TType.MAP, 
                new org.apache.storm.thrift.meta_data.StructMetaData(org.apache.storm.thrift.protocol.TType.STRUCT, GlobalStreamId.class), 
                new org.apache.storm.thrift.meta_data.FieldValueMetaData(org.apache.storm.thrift.protocol.TType.DOUBLE)))));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.storm.thrift.meta_data.FieldMetaData.addStructMetaDataMap(BoltStats.class, metaDataMap);
  }

  public BoltStats() {
  }

  public BoltStats(
    java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> acked,
    java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> failed,
    java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>> process_ms_avg,
    java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> executed,
    java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>> execute_ms_avg)
  {
    this();
    this.acked = acked;
    this.failed = failed;
    this.process_ms_avg = process_ms_avg;
    this.executed = executed;
    this.execute_ms_avg = execute_ms_avg;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public BoltStats(BoltStats other) {
    if (other.is_set_acked()) {
      java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> __this__acked = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(other.acked.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> other_element : other.acked.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Map<GlobalStreamId,java.lang.Long> other_element_value = other_element.getValue();

        java.lang.String __this__acked_copy_key = other_element_key;

        java.util.Map<GlobalStreamId,java.lang.Long> __this__acked_copy_value = new java.util.HashMap<GlobalStreamId,java.lang.Long>(other_element_value.size());
        for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> other_element_value_element : other_element_value.entrySet()) {

          GlobalStreamId other_element_value_element_key = other_element_value_element.getKey();
          java.lang.Long other_element_value_element_value = other_element_value_element.getValue();

          GlobalStreamId __this__acked_copy_value_copy_key = new GlobalStreamId(other_element_value_element_key);

          java.lang.Long __this__acked_copy_value_copy_value = other_element_value_element_value;

          __this__acked_copy_value.put(__this__acked_copy_value_copy_key, __this__acked_copy_value_copy_value);
        }

        __this__acked.put(__this__acked_copy_key, __this__acked_copy_value);
      }
      this.acked = __this__acked;
    }
    if (other.is_set_failed()) {
      java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> __this__failed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(other.failed.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> other_element : other.failed.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Map<GlobalStreamId,java.lang.Long> other_element_value = other_element.getValue();

        java.lang.String __this__failed_copy_key = other_element_key;

        java.util.Map<GlobalStreamId,java.lang.Long> __this__failed_copy_value = new java.util.HashMap<GlobalStreamId,java.lang.Long>(other_element_value.size());
        for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> other_element_value_element : other_element_value.entrySet()) {

          GlobalStreamId other_element_value_element_key = other_element_value_element.getKey();
          java.lang.Long other_element_value_element_value = other_element_value_element.getValue();

          GlobalStreamId __this__failed_copy_value_copy_key = new GlobalStreamId(other_element_value_element_key);

          java.lang.Long __this__failed_copy_value_copy_value = other_element_value_element_value;

          __this__failed_copy_value.put(__this__failed_copy_value_copy_key, __this__failed_copy_value_copy_value);
        }

        __this__failed.put(__this__failed_copy_key, __this__failed_copy_value);
      }
      this.failed = __this__failed;
    }
    if (other.is_set_process_ms_avg()) {
      java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>> __this__process_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(other.process_ms_avg.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> other_element : other.process_ms_avg.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Map<GlobalStreamId,java.lang.Double> other_element_value = other_element.getValue();

        java.lang.String __this__process_ms_avg_copy_key = other_element_key;

        java.util.Map<GlobalStreamId,java.lang.Double> __this__process_ms_avg_copy_value = new java.util.HashMap<GlobalStreamId,java.lang.Double>(other_element_value.size());
        for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> other_element_value_element : other_element_value.entrySet()) {

          GlobalStreamId other_element_value_element_key = other_element_value_element.getKey();
          java.lang.Double other_element_value_element_value = other_element_value_element.getValue();

          GlobalStreamId __this__process_ms_avg_copy_value_copy_key = new GlobalStreamId(other_element_value_element_key);

          java.lang.Double __this__process_ms_avg_copy_value_copy_value = other_element_value_element_value;

          __this__process_ms_avg_copy_value.put(__this__process_ms_avg_copy_value_copy_key, __this__process_ms_avg_copy_value_copy_value);
        }

        __this__process_ms_avg.put(__this__process_ms_avg_copy_key, __this__process_ms_avg_copy_value);
      }
      this.process_ms_avg = __this__process_ms_avg;
    }
    if (other.is_set_executed()) {
      java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>> __this__executed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(other.executed.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> other_element : other.executed.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Map<GlobalStreamId,java.lang.Long> other_element_value = other_element.getValue();

        java.lang.String __this__executed_copy_key = other_element_key;

        java.util.Map<GlobalStreamId,java.lang.Long> __this__executed_copy_value = new java.util.HashMap<GlobalStreamId,java.lang.Long>(other_element_value.size());
        for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> other_element_value_element : other_element_value.entrySet()) {

          GlobalStreamId other_element_value_element_key = other_element_value_element.getKey();
          java.lang.Long other_element_value_element_value = other_element_value_element.getValue();

          GlobalStreamId __this__executed_copy_value_copy_key = new GlobalStreamId(other_element_value_element_key);

          java.lang.Long __this__executed_copy_value_copy_value = other_element_value_element_value;

          __this__executed_copy_value.put(__this__executed_copy_value_copy_key, __this__executed_copy_value_copy_value);
        }

        __this__executed.put(__this__executed_copy_key, __this__executed_copy_value);
      }
      this.executed = __this__executed;
    }
    if (other.is_set_execute_ms_avg()) {
      java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>> __this__execute_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(other.execute_ms_avg.size());
      for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> other_element : other.execute_ms_avg.entrySet()) {

        java.lang.String other_element_key = other_element.getKey();
        java.util.Map<GlobalStreamId,java.lang.Double> other_element_value = other_element.getValue();

        java.lang.String __this__execute_ms_avg_copy_key = other_element_key;

        java.util.Map<GlobalStreamId,java.lang.Double> __this__execute_ms_avg_copy_value = new java.util.HashMap<GlobalStreamId,java.lang.Double>(other_element_value.size());
        for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> other_element_value_element : other_element_value.entrySet()) {

          GlobalStreamId other_element_value_element_key = other_element_value_element.getKey();
          java.lang.Double other_element_value_element_value = other_element_value_element.getValue();

          GlobalStreamId __this__execute_ms_avg_copy_value_copy_key = new GlobalStreamId(other_element_value_element_key);

          java.lang.Double __this__execute_ms_avg_copy_value_copy_value = other_element_value_element_value;

          __this__execute_ms_avg_copy_value.put(__this__execute_ms_avg_copy_value_copy_key, __this__execute_ms_avg_copy_value_copy_value);
        }

        __this__execute_ms_avg.put(__this__execute_ms_avg_copy_key, __this__execute_ms_avg_copy_value);
      }
      this.execute_ms_avg = __this__execute_ms_avg;
    }
  }

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

  @Override
  public void clear() {
    this.acked = null;
    this.failed = null;
    this.process_ms_avg = null;
    this.executed = null;
    this.execute_ms_avg = null;
  }

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

  public void put_to_acked(java.lang.String key, java.util.Map<GlobalStreamId,java.lang.Long> val) {
    if (this.acked == null) {
      this.acked = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>();
    }
    this.acked.put(key, val);
  }

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

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

  public void unset_acked() {
    this.acked = null;
  }

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

  public void set_acked_isSet(boolean value) {
    if (!value) {
      this.acked = null;
    }
  }

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

  public void put_to_failed(java.lang.String key, java.util.Map<GlobalStreamId,java.lang.Long> val) {
    if (this.failed == null) {
      this.failed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>();
    }
    this.failed.put(key, val);
  }

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

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

  public void unset_failed() {
    this.failed = null;
  }

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

  public void set_failed_isSet(boolean value) {
    if (!value) {
      this.failed = null;
    }
  }

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

  public void put_to_process_ms_avg(java.lang.String key, java.util.Map<GlobalStreamId,java.lang.Double> val) {
    if (this.process_ms_avg == null) {
      this.process_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>();
    }
    this.process_ms_avg.put(key, val);
  }

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

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

  public void unset_process_ms_avg() {
    this.process_ms_avg = null;
  }

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

  public void set_process_ms_avg_isSet(boolean value) {
    if (!value) {
      this.process_ms_avg = null;
    }
  }

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

  public void put_to_executed(java.lang.String key, java.util.Map<GlobalStreamId,java.lang.Long> val) {
    if (this.executed == null) {
      this.executed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>();
    }
    this.executed.put(key, val);
  }

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

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

  public void unset_executed() {
    this.executed = null;
  }

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

  public void set_executed_isSet(boolean value) {
    if (!value) {
      this.executed = null;
    }
  }

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

  public void put_to_execute_ms_avg(java.lang.String key, java.util.Map<GlobalStreamId,java.lang.Double> val) {
    if (this.execute_ms_avg == null) {
      this.execute_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>();
    }
    this.execute_ms_avg.put(key, val);
  }

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

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

  public void unset_execute_ms_avg() {
    this.execute_ms_avg = null;
  }

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

  public void set_execute_ms_avg_isSet(boolean value) {
    if (!value) {
      this.execute_ms_avg = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.storm.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case ACKED:
      if (value == null) {
        unset_acked();
      } else {
        set_acked((java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>)value);
      }
      break;

    case FAILED:
      if (value == null) {
        unset_failed();
      } else {
        set_failed((java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>)value);
      }
      break;

    case PROCESS_MS_AVG:
      if (value == null) {
        unset_process_ms_avg();
      } else {
        set_process_ms_avg((java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>)value);
      }
      break;

    case EXECUTED:
      if (value == null) {
        unset_executed();
      } else {
        set_executed((java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>)value);
      }
      break;

    case EXECUTE_MS_AVG:
      if (value == null) {
        unset_execute_ms_avg();
      } else {
        set_execute_ms_avg((java.util.Map<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>)value);
      }
      break;

    }
  }

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

    case FAILED:
      return get_failed();

    case PROCESS_MS_AVG:
      return get_process_ms_avg();

    case EXECUTED:
      return get_executed();

    case EXECUTE_MS_AVG:
      return get_execute_ms_avg();

    }
    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 ACKED:
      return is_set_acked();
    case FAILED:
      return is_set_failed();
    case PROCESS_MS_AVG:
      return is_set_process_ms_avg();
    case EXECUTED:
      return is_set_executed();
    case EXECUTE_MS_AVG:
      return is_set_execute_ms_avg();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_acked = true && this.is_set_acked();
    boolean that_present_acked = true && that.is_set_acked();
    if (this_present_acked || that_present_acked) {
      if (!(this_present_acked && that_present_acked))
        return false;
      if (!this.acked.equals(that.acked))
        return false;
    }

    boolean this_present_failed = true && this.is_set_failed();
    boolean that_present_failed = true && that.is_set_failed();
    if (this_present_failed || that_present_failed) {
      if (!(this_present_failed && that_present_failed))
        return false;
      if (!this.failed.equals(that.failed))
        return false;
    }

    boolean this_present_process_ms_avg = true && this.is_set_process_ms_avg();
    boolean that_present_process_ms_avg = true && that.is_set_process_ms_avg();
    if (this_present_process_ms_avg || that_present_process_ms_avg) {
      if (!(this_present_process_ms_avg && that_present_process_ms_avg))
        return false;
      if (!this.process_ms_avg.equals(that.process_ms_avg))
        return false;
    }

    boolean this_present_executed = true && this.is_set_executed();
    boolean that_present_executed = true && that.is_set_executed();
    if (this_present_executed || that_present_executed) {
      if (!(this_present_executed && that_present_executed))
        return false;
      if (!this.executed.equals(that.executed))
        return false;
    }

    boolean this_present_execute_ms_avg = true && this.is_set_execute_ms_avg();
    boolean that_present_execute_ms_avg = true && that.is_set_execute_ms_avg();
    if (this_present_execute_ms_avg || that_present_execute_ms_avg) {
      if (!(this_present_execute_ms_avg && that_present_execute_ms_avg))
        return false;
      if (!this.execute_ms_avg.equals(that.execute_ms_avg))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((is_set_acked()) ? 131071 : 524287);
    if (is_set_acked())
      hashCode = hashCode * 8191 + acked.hashCode();

    hashCode = hashCode * 8191 + ((is_set_failed()) ? 131071 : 524287);
    if (is_set_failed())
      hashCode = hashCode * 8191 + failed.hashCode();

    hashCode = hashCode * 8191 + ((is_set_process_ms_avg()) ? 131071 : 524287);
    if (is_set_process_ms_avg())
      hashCode = hashCode * 8191 + process_ms_avg.hashCode();

    hashCode = hashCode * 8191 + ((is_set_executed()) ? 131071 : 524287);
    if (is_set_executed())
      hashCode = hashCode * 8191 + executed.hashCode();

    hashCode = hashCode * 8191 + ((is_set_execute_ms_avg()) ? 131071 : 524287);
    if (is_set_execute_ms_avg())
      hashCode = hashCode * 8191 + execute_ms_avg.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.valueOf(is_set_acked()).compareTo(other.is_set_acked());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_acked()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.acked, other.acked);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_failed()).compareTo(other.is_set_failed());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_failed()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.failed, other.failed);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_process_ms_avg()).compareTo(other.is_set_process_ms_avg());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_process_ms_avg()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.process_ms_avg, other.process_ms_avg);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_executed()).compareTo(other.is_set_executed());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_executed()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.executed, other.executed);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.valueOf(is_set_execute_ms_avg()).compareTo(other.is_set_execute_ms_avg());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (is_set_execute_ms_avg()) {
      lastComparison = org.apache.storm.thrift.TBaseHelper.compareTo(this.execute_ms_avg, other.execute_ms_avg);
      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("BoltStats(");
    boolean first = true;

    sb.append("acked:");
    if (this.acked == null) {
      sb.append("null");
    } else {
      sb.append(this.acked);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("failed:");
    if (this.failed == null) {
      sb.append("null");
    } else {
      sb.append(this.failed);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("process_ms_avg:");
    if (this.process_ms_avg == null) {
      sb.append("null");
    } else {
      sb.append(this.process_ms_avg);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("executed:");
    if (this.executed == null) {
      sb.append("null");
    } else {
      sb.append(this.executed);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("execute_ms_avg:");
    if (this.execute_ms_avg == null) {
      sb.append("null");
    } else {
      sb.append(this.execute_ms_avg);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

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

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

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

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

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

  private static class BoltStatsStandardScheme extends org.apache.storm.thrift.scheme.StandardScheme<BoltStats> {

    public void read(org.apache.storm.thrift.protocol.TProtocol iprot, BoltStats 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: // ACKED
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map190 = iprot.readMapBegin();
                struct.acked = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map190.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key191;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val192;
                for (int _i193 = 0; _i193 < _map190.size; ++_i193)
                {
                  _key191 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map194 = iprot.readMapBegin();
                    _val192 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map194.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key195;
                    long _val196;
                    for (int _i197 = 0; _i197 < _map194.size; ++_i197)
                    {
                      _key195 = new GlobalStreamId();
                      _key195.read(iprot);
                      _val196 = iprot.readI64();
                      _val192.put(_key195, _val196);
                    }
                    iprot.readMapEnd();
                  }
                  struct.acked.put(_key191, _val192);
                }
                iprot.readMapEnd();
              }
              struct.set_acked_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // FAILED
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map198 = iprot.readMapBegin();
                struct.failed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map198.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key199;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val200;
                for (int _i201 = 0; _i201 < _map198.size; ++_i201)
                {
                  _key199 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map202 = iprot.readMapBegin();
                    _val200 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map202.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key203;
                    long _val204;
                    for (int _i205 = 0; _i205 < _map202.size; ++_i205)
                    {
                      _key203 = new GlobalStreamId();
                      _key203.read(iprot);
                      _val204 = iprot.readI64();
                      _val200.put(_key203, _val204);
                    }
                    iprot.readMapEnd();
                  }
                  struct.failed.put(_key199, _val200);
                }
                iprot.readMapEnd();
              }
              struct.set_failed_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // PROCESS_MS_AVG
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map206 = iprot.readMapBegin();
                struct.process_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(2*_map206.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key207;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val208;
                for (int _i209 = 0; _i209 < _map206.size; ++_i209)
                {
                  _key207 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map210 = iprot.readMapBegin();
                    _val208 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map210.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key211;
                    double _val212;
                    for (int _i213 = 0; _i213 < _map210.size; ++_i213)
                    {
                      _key211 = new GlobalStreamId();
                      _key211.read(iprot);
                      _val212 = iprot.readDouble();
                      _val208.put(_key211, _val212);
                    }
                    iprot.readMapEnd();
                  }
                  struct.process_ms_avg.put(_key207, _val208);
                }
                iprot.readMapEnd();
              }
              struct.set_process_ms_avg_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // EXECUTED
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map214 = iprot.readMapBegin();
                struct.executed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map214.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key215;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val216;
                for (int _i217 = 0; _i217 < _map214.size; ++_i217)
                {
                  _key215 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map218 = iprot.readMapBegin();
                    _val216 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map218.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key219;
                    long _val220;
                    for (int _i221 = 0; _i221 < _map218.size; ++_i221)
                    {
                      _key219 = new GlobalStreamId();
                      _key219.read(iprot);
                      _val220 = iprot.readI64();
                      _val216.put(_key219, _val220);
                    }
                    iprot.readMapEnd();
                  }
                  struct.executed.put(_key215, _val216);
                }
                iprot.readMapEnd();
              }
              struct.set_executed_isSet(true);
            } else { 
              org.apache.storm.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // EXECUTE_MS_AVG
            if (schemeField.type == org.apache.storm.thrift.protocol.TType.MAP) {
              {
                org.apache.storm.thrift.protocol.TMap _map222 = iprot.readMapBegin();
                struct.execute_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(2*_map222.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key223;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val224;
                for (int _i225 = 0; _i225 < _map222.size; ++_i225)
                {
                  _key223 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map226 = iprot.readMapBegin();
                    _val224 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map226.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key227;
                    double _val228;
                    for (int _i229 = 0; _i229 < _map226.size; ++_i229)
                    {
                      _key227 = new GlobalStreamId();
                      _key227.read(iprot);
                      _val228 = iprot.readDouble();
                      _val224.put(_key227, _val228);
                    }
                    iprot.readMapEnd();
                  }
                  struct.execute_ms_avg.put(_key223, _val224);
                }
                iprot.readMapEnd();
              }
              struct.set_execute_ms_avg_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, BoltStats struct) throws org.apache.storm.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.acked != null) {
        oprot.writeFieldBegin(ACKED_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, struct.acked.size()));
          for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter230 : struct.acked.entrySet())
          {
            oprot.writeString(_iter230.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, _iter230.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter231 : _iter230.getValue().entrySet())
              {
                _iter231.getKey().write(oprot);
                oprot.writeI64(_iter231.getValue());
              }
              oprot.writeMapEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.failed != null) {
        oprot.writeFieldBegin(FAILED_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, struct.failed.size()));
          for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter232 : struct.failed.entrySet())
          {
            oprot.writeString(_iter232.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, _iter232.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter233 : _iter232.getValue().entrySet())
              {
                _iter233.getKey().write(oprot);
                oprot.writeI64(_iter233.getValue());
              }
              oprot.writeMapEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.process_ms_avg != null) {
        oprot.writeFieldBegin(PROCESS_MS_AVG_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, struct.process_ms_avg.size()));
          for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> _iter234 : struct.process_ms_avg.entrySet())
          {
            oprot.writeString(_iter234.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, _iter234.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter235 : _iter234.getValue().entrySet())
              {
                _iter235.getKey().write(oprot);
                oprot.writeDouble(_iter235.getValue());
              }
              oprot.writeMapEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.executed != null) {
        oprot.writeFieldBegin(EXECUTED_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, struct.executed.size()));
          for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter236 : struct.executed.entrySet())
          {
            oprot.writeString(_iter236.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, _iter236.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter237 : _iter236.getValue().entrySet())
              {
                _iter237.getKey().write(oprot);
                oprot.writeI64(_iter237.getValue());
              }
              oprot.writeMapEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      if (struct.execute_ms_avg != null) {
        oprot.writeFieldBegin(EXECUTE_MS_AVG_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, struct.execute_ms_avg.size()));
          for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> _iter238 : struct.execute_ms_avg.entrySet())
          {
            oprot.writeString(_iter238.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, _iter238.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter239 : _iter238.getValue().entrySet())
              {
                _iter239.getKey().write(oprot);
                oprot.writeDouble(_iter239.getValue());
              }
              oprot.writeMapEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

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

  private static class BoltStatsTupleScheme extends org.apache.storm.thrift.scheme.TupleScheme<BoltStats> {

    @Override
    public void write(org.apache.storm.thrift.protocol.TProtocol prot, BoltStats struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol oprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      {
        oprot.writeI32(struct.acked.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter240 : struct.acked.entrySet())
        {
          oprot.writeString(_iter240.getKey());
          {
            oprot.writeI32(_iter240.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter241 : _iter240.getValue().entrySet())
            {
              _iter241.getKey().write(oprot);
              oprot.writeI64(_iter241.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.failed.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter242 : struct.failed.entrySet())
        {
          oprot.writeString(_iter242.getKey());
          {
            oprot.writeI32(_iter242.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter243 : _iter242.getValue().entrySet())
            {
              _iter243.getKey().write(oprot);
              oprot.writeI64(_iter243.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.process_ms_avg.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> _iter244 : struct.process_ms_avg.entrySet())
        {
          oprot.writeString(_iter244.getKey());
          {
            oprot.writeI32(_iter244.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter245 : _iter244.getValue().entrySet())
            {
              _iter245.getKey().write(oprot);
              oprot.writeDouble(_iter245.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.executed.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter246 : struct.executed.entrySet())
        {
          oprot.writeString(_iter246.getKey());
          {
            oprot.writeI32(_iter246.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter247 : _iter246.getValue().entrySet())
            {
              _iter247.getKey().write(oprot);
              oprot.writeI64(_iter247.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.execute_ms_avg.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> _iter248 : struct.execute_ms_avg.entrySet())
        {
          oprot.writeString(_iter248.getKey());
          {
            oprot.writeI32(_iter248.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter249 : _iter248.getValue().entrySet())
            {
              _iter249.getKey().write(oprot);
              oprot.writeDouble(_iter249.getValue());
            }
          }
        }
      }
    }

    @Override
    public void read(org.apache.storm.thrift.protocol.TProtocol prot, BoltStats struct) throws org.apache.storm.thrift.TException {
      org.apache.storm.thrift.protocol.TTupleProtocol iprot = (org.apache.storm.thrift.protocol.TTupleProtocol) prot;
      {
        org.apache.storm.thrift.protocol.TMap _map250 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, iprot.readI32());
        struct.acked = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map250.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key251;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val252;
        for (int _i253 = 0; _i253 < _map250.size; ++_i253)
        {
          _key251 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map254 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
            _val252 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map254.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key255;
            long _val256;
            for (int _i257 = 0; _i257 < _map254.size; ++_i257)
            {
              _key255 = new GlobalStreamId();
              _key255.read(iprot);
              _val256 = iprot.readI64();
              _val252.put(_key255, _val256);
            }
          }
          struct.acked.put(_key251, _val252);
        }
      }
      struct.set_acked_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map258 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, iprot.readI32());
        struct.failed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map258.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key259;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val260;
        for (int _i261 = 0; _i261 < _map258.size; ++_i261)
        {
          _key259 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map262 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
            _val260 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map262.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key263;
            long _val264;
            for (int _i265 = 0; _i265 < _map262.size; ++_i265)
            {
              _key263 = new GlobalStreamId();
              _key263.read(iprot);
              _val264 = iprot.readI64();
              _val260.put(_key263, _val264);
            }
          }
          struct.failed.put(_key259, _val260);
        }
      }
      struct.set_failed_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map266 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, iprot.readI32());
        struct.process_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(2*_map266.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key267;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val268;
        for (int _i269 = 0; _i269 < _map266.size; ++_i269)
        {
          _key267 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map270 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
            _val268 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map270.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key271;
            double _val272;
            for (int _i273 = 0; _i273 < _map270.size; ++_i273)
            {
              _key271 = new GlobalStreamId();
              _key271.read(iprot);
              _val272 = iprot.readDouble();
              _val268.put(_key271, _val272);
            }
          }
          struct.process_ms_avg.put(_key267, _val268);
        }
      }
      struct.set_process_ms_avg_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map274 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, iprot.readI32());
        struct.executed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map274.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key275;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val276;
        for (int _i277 = 0; _i277 < _map274.size; ++_i277)
        {
          _key275 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map278 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
            _val276 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map278.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key279;
            long _val280;
            for (int _i281 = 0; _i281 < _map278.size; ++_i281)
            {
              _key279 = new GlobalStreamId();
              _key279.read(iprot);
              _val280 = iprot.readI64();
              _val276.put(_key279, _val280);
            }
          }
          struct.executed.put(_key275, _val276);
        }
      }
      struct.set_executed_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map282 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRING, org.apache.storm.thrift.protocol.TType.MAP, iprot.readI32());
        struct.execute_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(2*_map282.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key283;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val284;
        for (int _i285 = 0; _i285 < _map282.size; ++_i285)
        {
          _key283 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map286 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
            _val284 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map286.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key287;
            double _val288;
            for (int _i289 = 0; _i289 < _map286.size; ++_i289)
            {
              _key287 = new GlobalStreamId();
              _key287.read(iprot);
              _val288 = iprot.readDouble();
              _val284.put(_key287, _val288);
            }
          }
          struct.execute_ms_avg.put(_key283, _val284);
        }
      }
      struct.set_execute_ms_avg_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();
  }
}

