/**
 * Autogenerated by Thrift Compiler (0.14.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.hadoop.hbase.thrift2.generated;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
/**
 * Thrift wrapper around
 * org.apache.hadoop.hbase.client.LogQueryFilter
 */
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.14.1)", date = "2021-07-19")
public class TLogQueryFilter implements org.apache.thrift.TBase<TLogQueryFilter, TLogQueryFilter._Fields>, java.io.Serializable, Cloneable, Comparable<TLogQueryFilter> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TLogQueryFilter");

  private static final org.apache.thrift.protocol.TField REGION_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("regionName", org.apache.thrift.protocol.TType.STRING, (short)1);
  private static final org.apache.thrift.protocol.TField CLIENT_ADDRESS_FIELD_DESC = new org.apache.thrift.protocol.TField("clientAddress", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField TABLE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tableName", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField USER_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("userName", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);
  private static final org.apache.thrift.protocol.TField LOG_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("logType", org.apache.thrift.protocol.TType.I32, (short)6);
  private static final org.apache.thrift.protocol.TField FILTER_BY_OPERATOR_FIELD_DESC = new org.apache.thrift.protocol.TField("filterByOperator", org.apache.thrift.protocol.TType.I32, (short)7);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TLogQueryFilterStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TLogQueryFilterTupleSchemeFactory();

  public @org.apache.thrift.annotation.Nullable java.lang.String regionName; // optional
  public @org.apache.thrift.annotation.Nullable java.lang.String clientAddress; // optional
  public @org.apache.thrift.annotation.Nullable java.lang.String tableName; // optional
  public @org.apache.thrift.annotation.Nullable java.lang.String userName; // optional
  public int limit; // optional
  /**
   * 
   * @see TLogType
   */
  public @org.apache.thrift.annotation.Nullable TLogType logType; // optional
  /**
   * 
   * @see TFilterByOperator
   */
  public @org.apache.thrift.annotation.Nullable TFilterByOperator filterByOperator; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    REGION_NAME((short)1, "regionName"),
    CLIENT_ADDRESS((short)2, "clientAddress"),
    TABLE_NAME((short)3, "tableName"),
    USER_NAME((short)4, "userName"),
    LIMIT((short)5, "limit"),
    /**
     * 
     * @see TLogType
     */
    LOG_TYPE((short)6, "logType"),
    /**
     * 
     * @see TFilterByOperator
     */
    FILTER_BY_OPERATOR((short)7, "filterByOperator");

    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.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // REGION_NAME
          return REGION_NAME;
        case 2: // CLIENT_ADDRESS
          return CLIENT_ADDRESS;
        case 3: // TABLE_NAME
          return TABLE_NAME;
        case 4: // USER_NAME
          return USER_NAME;
        case 5: // LIMIT
          return LIMIT;
        case 6: // LOG_TYPE
          return LOG_TYPE;
        case 7: // FILTER_BY_OPERATOR
          return FILTER_BY_OPERATOR;
        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.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

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

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

    public short getThriftFieldId() {
      return _thriftId;
    }

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

  // isset id assignments
  private static final int __LIMIT_ISSET_ID = 0;
  private byte __isset_bitfield = 0;
  private static final _Fields optionals[] = {_Fields.REGION_NAME,_Fields.CLIENT_ADDRESS,_Fields.TABLE_NAME,_Fields.USER_NAME,_Fields.LIMIT,_Fields.LOG_TYPE,_Fields.FILTER_BY_OPERATOR};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.REGION_NAME, new org.apache.thrift.meta_data.FieldMetaData("regionName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.CLIENT_ADDRESS, new org.apache.thrift.meta_data.FieldMetaData("clientAddress", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TABLE_NAME, new org.apache.thrift.meta_data.FieldMetaData("tableName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.USER_NAME, new org.apache.thrift.meta_data.FieldMetaData("userName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
    tmpMap.put(_Fields.LOG_TYPE, new org.apache.thrift.meta_data.FieldMetaData("logType", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TLogType.class)));
    tmpMap.put(_Fields.FILTER_BY_OPERATOR, new org.apache.thrift.meta_data.FieldMetaData("filterByOperator", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, TFilterByOperator.class)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TLogQueryFilter.class, metaDataMap);
  }

  public TLogQueryFilter() {
    this.limit = 10;

    this.logType = org.apache.hadoop.hbase.thrift2.generated.TLogType.SLOW_LOG;

    this.filterByOperator = org.apache.hadoop.hbase.thrift2.generated.TFilterByOperator.OR;

  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TLogQueryFilter(TLogQueryFilter other) {
    __isset_bitfield = other.__isset_bitfield;
    if (other.isSetRegionName()) {
      this.regionName = other.regionName;
    }
    if (other.isSetClientAddress()) {
      this.clientAddress = other.clientAddress;
    }
    if (other.isSetTableName()) {
      this.tableName = other.tableName;
    }
    if (other.isSetUserName()) {
      this.userName = other.userName;
    }
    this.limit = other.limit;
    if (other.isSetLogType()) {
      this.logType = other.logType;
    }
    if (other.isSetFilterByOperator()) {
      this.filterByOperator = other.filterByOperator;
    }
  }

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

  @Override
  public void clear() {
    this.regionName = null;
    this.clientAddress = null;
    this.tableName = null;
    this.userName = null;
    this.limit = 10;

    this.logType = org.apache.hadoop.hbase.thrift2.generated.TLogType.SLOW_LOG;

    this.filterByOperator = org.apache.hadoop.hbase.thrift2.generated.TFilterByOperator.OR;

  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getRegionName() {
    return this.regionName;
  }

  public TLogQueryFilter setRegionName(@org.apache.thrift.annotation.Nullable java.lang.String regionName) {
    this.regionName = regionName;
    return this;
  }

  public void unsetRegionName() {
    this.regionName = null;
  }

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

  public void setRegionNameIsSet(boolean value) {
    if (!value) {
      this.regionName = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getClientAddress() {
    return this.clientAddress;
  }

  public TLogQueryFilter setClientAddress(@org.apache.thrift.annotation.Nullable java.lang.String clientAddress) {
    this.clientAddress = clientAddress;
    return this;
  }

  public void unsetClientAddress() {
    this.clientAddress = null;
  }

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

  public void setClientAddressIsSet(boolean value) {
    if (!value) {
      this.clientAddress = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getTableName() {
    return this.tableName;
  }

  public TLogQueryFilter setTableName(@org.apache.thrift.annotation.Nullable java.lang.String tableName) {
    this.tableName = tableName;
    return this;
  }

  public void unsetTableName() {
    this.tableName = null;
  }

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

  public void setTableNameIsSet(boolean value) {
    if (!value) {
      this.tableName = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getUserName() {
    return this.userName;
  }

  public TLogQueryFilter setUserName(@org.apache.thrift.annotation.Nullable java.lang.String userName) {
    this.userName = userName;
    return this;
  }

  public void unsetUserName() {
    this.userName = null;
  }

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

  public void setUserNameIsSet(boolean value) {
    if (!value) {
      this.userName = null;
    }
  }

  public int getLimit() {
    return this.limit;
  }

  public TLogQueryFilter setLimit(int limit) {
    this.limit = limit;
    setLimitIsSet(true);
    return this;
  }

  public void unsetLimit() {
    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
  }

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

  public void setLimitIsSet(boolean value) {
    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
  }

  /**
   * 
   * @see TLogType
   */
  @org.apache.thrift.annotation.Nullable
  public TLogType getLogType() {
    return this.logType;
  }

  /**
   * 
   * @see TLogType
   */
  public TLogQueryFilter setLogType(@org.apache.thrift.annotation.Nullable TLogType logType) {
    this.logType = logType;
    return this;
  }

  public void unsetLogType() {
    this.logType = null;
  }

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

  public void setLogTypeIsSet(boolean value) {
    if (!value) {
      this.logType = null;
    }
  }

  /**
   * 
   * @see TFilterByOperator
   */
  @org.apache.thrift.annotation.Nullable
  public TFilterByOperator getFilterByOperator() {
    return this.filterByOperator;
  }

  /**
   * 
   * @see TFilterByOperator
   */
  public TLogQueryFilter setFilterByOperator(@org.apache.thrift.annotation.Nullable TFilterByOperator filterByOperator) {
    this.filterByOperator = filterByOperator;
    return this;
  }

  public void unsetFilterByOperator() {
    this.filterByOperator = null;
  }

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

  public void setFilterByOperatorIsSet(boolean value) {
    if (!value) {
      this.filterByOperator = null;
    }
  }

  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case REGION_NAME:
      if (value == null) {
        unsetRegionName();
      } else {
        setRegionName((java.lang.String)value);
      }
      break;

    case CLIENT_ADDRESS:
      if (value == null) {
        unsetClientAddress();
      } else {
        setClientAddress((java.lang.String)value);
      }
      break;

    case TABLE_NAME:
      if (value == null) {
        unsetTableName();
      } else {
        setTableName((java.lang.String)value);
      }
      break;

    case USER_NAME:
      if (value == null) {
        unsetUserName();
      } else {
        setUserName((java.lang.String)value);
      }
      break;

    case LIMIT:
      if (value == null) {
        unsetLimit();
      } else {
        setLimit((java.lang.Integer)value);
      }
      break;

    case LOG_TYPE:
      if (value == null) {
        unsetLogType();
      } else {
        setLogType((TLogType)value);
      }
      break;

    case FILTER_BY_OPERATOR:
      if (value == null) {
        unsetFilterByOperator();
      } else {
        setFilterByOperator((TFilterByOperator)value);
      }
      break;

    }
  }

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

    case CLIENT_ADDRESS:
      return getClientAddress();

    case TABLE_NAME:
      return getTableName();

    case USER_NAME:
      return getUserName();

    case LIMIT:
      return getLimit();

    case LOG_TYPE:
      return getLogType();

    case FILTER_BY_OPERATOR:
      return getFilterByOperator();

    }
    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 REGION_NAME:
      return isSetRegionName();
    case CLIENT_ADDRESS:
      return isSetClientAddress();
    case TABLE_NAME:
      return isSetTableName();
    case USER_NAME:
      return isSetUserName();
    case LIMIT:
      return isSetLimit();
    case LOG_TYPE:
      return isSetLogType();
    case FILTER_BY_OPERATOR:
      return isSetFilterByOperator();
    }
    throw new java.lang.IllegalStateException();
  }

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

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

    boolean this_present_regionName = true && this.isSetRegionName();
    boolean that_present_regionName = true && that.isSetRegionName();
    if (this_present_regionName || that_present_regionName) {
      if (!(this_present_regionName && that_present_regionName))
        return false;
      if (!this.regionName.equals(that.regionName))
        return false;
    }

    boolean this_present_clientAddress = true && this.isSetClientAddress();
    boolean that_present_clientAddress = true && that.isSetClientAddress();
    if (this_present_clientAddress || that_present_clientAddress) {
      if (!(this_present_clientAddress && that_present_clientAddress))
        return false;
      if (!this.clientAddress.equals(that.clientAddress))
        return false;
    }

    boolean this_present_tableName = true && this.isSetTableName();
    boolean that_present_tableName = true && that.isSetTableName();
    if (this_present_tableName || that_present_tableName) {
      if (!(this_present_tableName && that_present_tableName))
        return false;
      if (!this.tableName.equals(that.tableName))
        return false;
    }

    boolean this_present_userName = true && this.isSetUserName();
    boolean that_present_userName = true && that.isSetUserName();
    if (this_present_userName || that_present_userName) {
      if (!(this_present_userName && that_present_userName))
        return false;
      if (!this.userName.equals(that.userName))
        return false;
    }

    boolean this_present_limit = true && this.isSetLimit();
    boolean that_present_limit = true && that.isSetLimit();
    if (this_present_limit || that_present_limit) {
      if (!(this_present_limit && that_present_limit))
        return false;
      if (this.limit != that.limit)
        return false;
    }

    boolean this_present_logType = true && this.isSetLogType();
    boolean that_present_logType = true && that.isSetLogType();
    if (this_present_logType || that_present_logType) {
      if (!(this_present_logType && that_present_logType))
        return false;
      if (!this.logType.equals(that.logType))
        return false;
    }

    boolean this_present_filterByOperator = true && this.isSetFilterByOperator();
    boolean that_present_filterByOperator = true && that.isSetFilterByOperator();
    if (this_present_filterByOperator || that_present_filterByOperator) {
      if (!(this_present_filterByOperator && that_present_filterByOperator))
        return false;
      if (!this.filterByOperator.equals(that.filterByOperator))
        return false;
    }

    return true;
  }

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

    hashCode = hashCode * 8191 + ((isSetRegionName()) ? 131071 : 524287);
    if (isSetRegionName())
      hashCode = hashCode * 8191 + regionName.hashCode();

    hashCode = hashCode * 8191 + ((isSetClientAddress()) ? 131071 : 524287);
    if (isSetClientAddress())
      hashCode = hashCode * 8191 + clientAddress.hashCode();

    hashCode = hashCode * 8191 + ((isSetTableName()) ? 131071 : 524287);
    if (isSetTableName())
      hashCode = hashCode * 8191 + tableName.hashCode();

    hashCode = hashCode * 8191 + ((isSetUserName()) ? 131071 : 524287);
    if (isSetUserName())
      hashCode = hashCode * 8191 + userName.hashCode();

    hashCode = hashCode * 8191 + ((isSetLimit()) ? 131071 : 524287);
    if (isSetLimit())
      hashCode = hashCode * 8191 + limit;

    hashCode = hashCode * 8191 + ((isSetLogType()) ? 131071 : 524287);
    if (isSetLogType())
      hashCode = hashCode * 8191 + logType.getValue();

    hashCode = hashCode * 8191 + ((isSetFilterByOperator()) ? 131071 : 524287);
    if (isSetFilterByOperator())
      hashCode = hashCode * 8191 + filterByOperator.getValue();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetRegionName(), other.isSetRegionName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetRegionName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.regionName, other.regionName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetClientAddress(), other.isSetClientAddress());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetClientAddress()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.clientAddress, other.clientAddress);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTableName(), other.isSetTableName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTableName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tableName, other.tableName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetUserName(), other.isSetUserName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetUserName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userName, other.userName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetLimit(), other.isSetLimit());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLimit()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetLogType(), other.isSetLogType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetLogType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.logType, other.logType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetFilterByOperator(), other.isSetFilterByOperator());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetFilterByOperator()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.filterByOperator, other.filterByOperator);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

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

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

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

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

    if (isSetRegionName()) {
      sb.append("regionName:");
      if (this.regionName == null) {
        sb.append("null");
      } else {
        sb.append(this.regionName);
      }
      first = false;
    }
    if (isSetClientAddress()) {
      if (!first) sb.append(", ");
      sb.append("clientAddress:");
      if (this.clientAddress == null) {
        sb.append("null");
      } else {
        sb.append(this.clientAddress);
      }
      first = false;
    }
    if (isSetTableName()) {
      if (!first) sb.append(", ");
      sb.append("tableName:");
      if (this.tableName == null) {
        sb.append("null");
      } else {
        sb.append(this.tableName);
      }
      first = false;
    }
    if (isSetUserName()) {
      if (!first) sb.append(", ");
      sb.append("userName:");
      if (this.userName == null) {
        sb.append("null");
      } else {
        sb.append(this.userName);
      }
      first = false;
    }
    if (isSetLimit()) {
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
    }
    if (isSetLogType()) {
      if (!first) sb.append(", ");
      sb.append("logType:");
      if (this.logType == null) {
        sb.append("null");
      } else {
        sb.append(this.logType);
      }
      first = false;
    }
    if (isSetFilterByOperator()) {
      if (!first) sb.append(", ");
      sb.append("filterByOperator:");
      if (this.filterByOperator == null) {
        sb.append("null");
      } else {
        sb.append(this.filterByOperator);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class TLogQueryFilterStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public TLogQueryFilterStandardScheme getScheme() {
      return new TLogQueryFilterStandardScheme();
    }
  }

  private static class TLogQueryFilterStandardScheme extends org.apache.thrift.scheme.StandardScheme<TLogQueryFilter> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TLogQueryFilter struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // REGION_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.regionName = iprot.readString();
              struct.setRegionNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // CLIENT_ADDRESS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.clientAddress = iprot.readString();
              struct.setClientAddressIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // TABLE_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.tableName = iprot.readString();
              struct.setTableNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // USER_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.userName = iprot.readString();
              struct.setUserNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // LIMIT
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.limit = iprot.readI32();
              struct.setLimitIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // LOG_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.logType = org.apache.hadoop.hbase.thrift2.generated.TLogType.findByValue(iprot.readI32());
              struct.setLogTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // FILTER_BY_OPERATOR
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.filterByOperator = org.apache.hadoop.hbase.thrift2.generated.TFilterByOperator.findByValue(iprot.readI32());
              struct.setFilterByOperatorIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.regionName != null) {
        if (struct.isSetRegionName()) {
          oprot.writeFieldBegin(REGION_NAME_FIELD_DESC);
          oprot.writeString(struct.regionName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.clientAddress != null) {
        if (struct.isSetClientAddress()) {
          oprot.writeFieldBegin(CLIENT_ADDRESS_FIELD_DESC);
          oprot.writeString(struct.clientAddress);
          oprot.writeFieldEnd();
        }
      }
      if (struct.tableName != null) {
        if (struct.isSetTableName()) {
          oprot.writeFieldBegin(TABLE_NAME_FIELD_DESC);
          oprot.writeString(struct.tableName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.userName != null) {
        if (struct.isSetUserName()) {
          oprot.writeFieldBegin(USER_NAME_FIELD_DESC);
          oprot.writeString(struct.userName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.isSetLimit()) {
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
      }
      if (struct.logType != null) {
        if (struct.isSetLogType()) {
          oprot.writeFieldBegin(LOG_TYPE_FIELD_DESC);
          oprot.writeI32(struct.logType.getValue());
          oprot.writeFieldEnd();
        }
      }
      if (struct.filterByOperator != null) {
        if (struct.isSetFilterByOperator()) {
          oprot.writeFieldBegin(FILTER_BY_OPERATOR_FIELD_DESC);
          oprot.writeI32(struct.filterByOperator.getValue());
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TLogQueryFilterTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public TLogQueryFilterTupleScheme getScheme() {
      return new TLogQueryFilterTupleScheme();
    }
  }

  private static class TLogQueryFilterTupleScheme extends org.apache.thrift.scheme.TupleScheme<TLogQueryFilter> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TLogQueryFilter struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetRegionName()) {
        optionals.set(0);
      }
      if (struct.isSetClientAddress()) {
        optionals.set(1);
      }
      if (struct.isSetTableName()) {
        optionals.set(2);
      }
      if (struct.isSetUserName()) {
        optionals.set(3);
      }
      if (struct.isSetLimit()) {
        optionals.set(4);
      }
      if (struct.isSetLogType()) {
        optionals.set(5);
      }
      if (struct.isSetFilterByOperator()) {
        optionals.set(6);
      }
      oprot.writeBitSet(optionals, 7);
      if (struct.isSetRegionName()) {
        oprot.writeString(struct.regionName);
      }
      if (struct.isSetClientAddress()) {
        oprot.writeString(struct.clientAddress);
      }
      if (struct.isSetTableName()) {
        oprot.writeString(struct.tableName);
      }
      if (struct.isSetUserName()) {
        oprot.writeString(struct.userName);
      }
      if (struct.isSetLimit()) {
        oprot.writeI32(struct.limit);
      }
      if (struct.isSetLogType()) {
        oprot.writeI32(struct.logType.getValue());
      }
      if (struct.isSetFilterByOperator()) {
        oprot.writeI32(struct.filterByOperator.getValue());
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TLogQueryFilter struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(7);
      if (incoming.get(0)) {
        struct.regionName = iprot.readString();
        struct.setRegionNameIsSet(true);
      }
      if (incoming.get(1)) {
        struct.clientAddress = iprot.readString();
        struct.setClientAddressIsSet(true);
      }
      if (incoming.get(2)) {
        struct.tableName = iprot.readString();
        struct.setTableNameIsSet(true);
      }
      if (incoming.get(3)) {
        struct.userName = iprot.readString();
        struct.setUserNameIsSet(true);
      }
      if (incoming.get(4)) {
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
      if (incoming.get(5)) {
        struct.logType = org.apache.hadoop.hbase.thrift2.generated.TLogType.findByValue(iprot.readI32());
        struct.setLogTypeIsSet(true);
      }
      if (incoming.get(6)) {
        struct.filterByOperator = org.apache.hadoop.hbase.thrift2.generated.TFilterByOperator.findByValue(iprot.readI32());
        struct.setFilterByOperatorIsSet(true);
      }
    }
  }

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

