/**
 * 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 _map160 = iprot.readMapBegin();
                struct.acked = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map160.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key161;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val162;
                for (int _i163 = 0; _i163 < _map160.size; ++_i163)
                {
                  _key161 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map164 = iprot.readMapBegin();
                    _val162 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map164.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key165;
                    long _val166;
                    for (int _i167 = 0; _i167 < _map164.size; ++_i167)
                    {
                      _key165 = new GlobalStreamId();
                      _key165.read(iprot);
                      _val166 = iprot.readI64();
                      _val162.put(_key165, _val166);
                    }
                    iprot.readMapEnd();
                  }
                  struct.acked.put(_key161, _val162);
                }
                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 _map168 = iprot.readMapBegin();
                struct.failed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map168.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key169;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val170;
                for (int _i171 = 0; _i171 < _map168.size; ++_i171)
                {
                  _key169 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map172 = iprot.readMapBegin();
                    _val170 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map172.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key173;
                    long _val174;
                    for (int _i175 = 0; _i175 < _map172.size; ++_i175)
                    {
                      _key173 = new GlobalStreamId();
                      _key173.read(iprot);
                      _val174 = iprot.readI64();
                      _val170.put(_key173, _val174);
                    }
                    iprot.readMapEnd();
                  }
                  struct.failed.put(_key169, _val170);
                }
                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 _map176 = iprot.readMapBegin();
                struct.process_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(2*_map176.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key177;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val178;
                for (int _i179 = 0; _i179 < _map176.size; ++_i179)
                {
                  _key177 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map180 = iprot.readMapBegin();
                    _val178 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map180.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key181;
                    double _val182;
                    for (int _i183 = 0; _i183 < _map180.size; ++_i183)
                    {
                      _key181 = new GlobalStreamId();
                      _key181.read(iprot);
                      _val182 = iprot.readDouble();
                      _val178.put(_key181, _val182);
                    }
                    iprot.readMapEnd();
                  }
                  struct.process_ms_avg.put(_key177, _val178);
                }
                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 _map184 = iprot.readMapBegin();
                struct.executed = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Long>>(2*_map184.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key185;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val186;
                for (int _i187 = 0; _i187 < _map184.size; ++_i187)
                {
                  _key185 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map188 = iprot.readMapBegin();
                    _val186 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map188.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key189;
                    long _val190;
                    for (int _i191 = 0; _i191 < _map188.size; ++_i191)
                    {
                      _key189 = new GlobalStreamId();
                      _key189.read(iprot);
                      _val190 = iprot.readI64();
                      _val186.put(_key189, _val190);
                    }
                    iprot.readMapEnd();
                  }
                  struct.executed.put(_key185, _val186);
                }
                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 _map192 = iprot.readMapBegin();
                struct.execute_ms_avg = new java.util.HashMap<java.lang.String,java.util.Map<GlobalStreamId,java.lang.Double>>(2*_map192.size);
                @org.apache.storm.thrift.annotation.Nullable java.lang.String _key193;
                @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val194;
                for (int _i195 = 0; _i195 < _map192.size; ++_i195)
                {
                  _key193 = iprot.readString();
                  {
                    org.apache.storm.thrift.protocol.TMap _map196 = iprot.readMapBegin();
                    _val194 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map196.size);
                    @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key197;
                    double _val198;
                    for (int _i199 = 0; _i199 < _map196.size; ++_i199)
                    {
                      _key197 = new GlobalStreamId();
                      _key197.read(iprot);
                      _val198 = iprot.readDouble();
                      _val194.put(_key197, _val198);
                    }
                    iprot.readMapEnd();
                  }
                  struct.execute_ms_avg.put(_key193, _val194);
                }
                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>> _iter200 : struct.acked.entrySet())
          {
            oprot.writeString(_iter200.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, _iter200.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter201 : _iter200.getValue().entrySet())
              {
                _iter201.getKey().write(oprot);
                oprot.writeI64(_iter201.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>> _iter202 : struct.failed.entrySet())
          {
            oprot.writeString(_iter202.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, _iter202.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter203 : _iter202.getValue().entrySet())
              {
                _iter203.getKey().write(oprot);
                oprot.writeI64(_iter203.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>> _iter204 : struct.process_ms_avg.entrySet())
          {
            oprot.writeString(_iter204.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, _iter204.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter205 : _iter204.getValue().entrySet())
              {
                _iter205.getKey().write(oprot);
                oprot.writeDouble(_iter205.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>> _iter206 : struct.executed.entrySet())
          {
            oprot.writeString(_iter206.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, _iter206.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter207 : _iter206.getValue().entrySet())
              {
                _iter207.getKey().write(oprot);
                oprot.writeI64(_iter207.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>> _iter208 : struct.execute_ms_avg.entrySet())
          {
            oprot.writeString(_iter208.getKey());
            {
              oprot.writeMapBegin(new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, _iter208.getValue().size()));
              for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter209 : _iter208.getValue().entrySet())
              {
                _iter209.getKey().write(oprot);
                oprot.writeDouble(_iter209.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>> _iter210 : struct.acked.entrySet())
        {
          oprot.writeString(_iter210.getKey());
          {
            oprot.writeI32(_iter210.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter211 : _iter210.getValue().entrySet())
            {
              _iter211.getKey().write(oprot);
              oprot.writeI64(_iter211.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.failed.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter212 : struct.failed.entrySet())
        {
          oprot.writeString(_iter212.getKey());
          {
            oprot.writeI32(_iter212.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter213 : _iter212.getValue().entrySet())
            {
              _iter213.getKey().write(oprot);
              oprot.writeI64(_iter213.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.process_ms_avg.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> _iter214 : struct.process_ms_avg.entrySet())
        {
          oprot.writeString(_iter214.getKey());
          {
            oprot.writeI32(_iter214.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter215 : _iter214.getValue().entrySet())
            {
              _iter215.getKey().write(oprot);
              oprot.writeDouble(_iter215.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.executed.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Long>> _iter216 : struct.executed.entrySet())
        {
          oprot.writeString(_iter216.getKey());
          {
            oprot.writeI32(_iter216.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Long> _iter217 : _iter216.getValue().entrySet())
            {
              _iter217.getKey().write(oprot);
              oprot.writeI64(_iter217.getValue());
            }
          }
        }
      }
      {
        oprot.writeI32(struct.execute_ms_avg.size());
        for (java.util.Map.Entry<java.lang.String, java.util.Map<GlobalStreamId,java.lang.Double>> _iter218 : struct.execute_ms_avg.entrySet())
        {
          oprot.writeString(_iter218.getKey());
          {
            oprot.writeI32(_iter218.getValue().size());
            for (java.util.Map.Entry<GlobalStreamId, java.lang.Double> _iter219 : _iter218.getValue().entrySet())
            {
              _iter219.getKey().write(oprot);
              oprot.writeDouble(_iter219.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 _map220 = 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*_map220.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key221;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val222;
        for (int _i223 = 0; _i223 < _map220.size; ++_i223)
        {
          _key221 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map224 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
            _val222 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map224.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key225;
            long _val226;
            for (int _i227 = 0; _i227 < _map224.size; ++_i227)
            {
              _key225 = new GlobalStreamId();
              _key225.read(iprot);
              _val226 = iprot.readI64();
              _val222.put(_key225, _val226);
            }
          }
          struct.acked.put(_key221, _val222);
        }
      }
      struct.set_acked_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map228 = 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*_map228.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key229;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val230;
        for (int _i231 = 0; _i231 < _map228.size; ++_i231)
        {
          _key229 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map232 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
            _val230 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map232.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key233;
            long _val234;
            for (int _i235 = 0; _i235 < _map232.size; ++_i235)
            {
              _key233 = new GlobalStreamId();
              _key233.read(iprot);
              _val234 = iprot.readI64();
              _val230.put(_key233, _val234);
            }
          }
          struct.failed.put(_key229, _val230);
        }
      }
      struct.set_failed_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map236 = 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*_map236.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key237;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val238;
        for (int _i239 = 0; _i239 < _map236.size; ++_i239)
        {
          _key237 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map240 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
            _val238 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map240.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key241;
            double _val242;
            for (int _i243 = 0; _i243 < _map240.size; ++_i243)
            {
              _key241 = new GlobalStreamId();
              _key241.read(iprot);
              _val242 = iprot.readDouble();
              _val238.put(_key241, _val242);
            }
          }
          struct.process_ms_avg.put(_key237, _val238);
        }
      }
      struct.set_process_ms_avg_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map244 = 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*_map244.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key245;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Long> _val246;
        for (int _i247 = 0; _i247 < _map244.size; ++_i247)
        {
          _key245 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map248 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.I64, iprot.readI32());
            _val246 = new java.util.HashMap<GlobalStreamId,java.lang.Long>(2*_map248.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key249;
            long _val250;
            for (int _i251 = 0; _i251 < _map248.size; ++_i251)
            {
              _key249 = new GlobalStreamId();
              _key249.read(iprot);
              _val250 = iprot.readI64();
              _val246.put(_key249, _val250);
            }
          }
          struct.executed.put(_key245, _val246);
        }
      }
      struct.set_executed_isSet(true);
      {
        org.apache.storm.thrift.protocol.TMap _map252 = 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*_map252.size);
        @org.apache.storm.thrift.annotation.Nullable java.lang.String _key253;
        @org.apache.storm.thrift.annotation.Nullable java.util.Map<GlobalStreamId,java.lang.Double> _val254;
        for (int _i255 = 0; _i255 < _map252.size; ++_i255)
        {
          _key253 = iprot.readString();
          {
            org.apache.storm.thrift.protocol.TMap _map256 = new org.apache.storm.thrift.protocol.TMap(org.apache.storm.thrift.protocol.TType.STRUCT, org.apache.storm.thrift.protocol.TType.DOUBLE, iprot.readI32());
            _val254 = new java.util.HashMap<GlobalStreamId,java.lang.Double>(2*_map256.size);
            @org.apache.storm.thrift.annotation.Nullable GlobalStreamId _key257;
            double _val258;
            for (int _i259 = 0; _i259 < _map256.size; ++_i259)
            {
              _key257 = new GlobalStreamId();
              _key257.read(iprot);
              _val258 = iprot.readDouble();
              _val254.put(_key257, _val258);
            }
          }
          struct.execute_ms_avg.put(_key253, _val254);
        }
      }
      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();
  }
}

