class GridCacheQueryDetailMetricsKey {
    /** Query type to track metrics. */
    private final GridCacheQueryType qryType;

    /** Textual query representation. */
    private final String qry;

    /** Pre-calculated hash code. */
    private final int hash;

    /**
     * Constructor.
     *
     * @param qryType Query type.
     * @param qry Textual query representation.
     */
    public GridCacheQueryDetailMetricsKey(GridCacheQueryType qryType, String qry) {
        assert qryType != null;
        assert qryType != GridCacheQueryType.SQL_FIELDS || qry != null;

        this.qryType = qryType;
        this.qry = qry;

        hash = 31 * qryType.hashCode() + (qry != null ? qry.hashCode() : 0);
    }

    /**
     * @return Query type.
     */
    public GridCacheQueryType getQueryType() {
        return qryType;
    }

    /**
     * @return Textual representation of query.
     */
    public String getQuery() {
        return qry;
    }

    /** {@inheritDoc} */
    @Override public int hashCode() {
        return hash;
    }

    /** {@inheritDoc} */
    @Override public boolean equals(Object o) {<FILL_FUNCTION_BODY>}
}

        if (this == o)
            return true;

        if (o == null || getClass() != o.getClass())
            return false;

        GridCacheQueryDetailMetricsKey other = (GridCacheQueryDetailMetricsKey)o;

        return qryType == other.qryType && F.eq(qry, other.qry);
    
<no_super_class>