package com.tangosol.examples.util.filter; import com.tangosol.io.ExternalizableLite; import com.tangosol.io.pof.PofReader; import com.tangosol.io.pof.PofWriter; import com.tangosol.io.pof.PortableObject; import com.tangosol.net.CacheFactory; import com.tangosol.util.Base; import com.tangosol.util.ExternalizableHelper; import com.tangosol.util.Filter; import com.tangosol.util.filter.IndexAwareFilter; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Map; import java.util.Set; /** * Filter which profiles evaluation of another filter. * *

* Usage example: *

* Filter filter     = new GreaterFilter("getFoo", 22);
* Set    setResults = cache.entrySet(new ProfilerFilter(filter));
* 
* If coherence.profilerfilter.logwarnings system property is true and * "getFoo" index is missing, ProfilerFilter will log a warning. * If coherence.profilerfilter.logtimes system property is true filter * execution time will be logged. * * @author dr 2008.02.15 */ public class ProfilerFilter extends Base implements Filter, IndexAwareFilter, ExternalizableLite, PortableObject { // ----- constructors --------------------------------------------------- /** * Default constructor (necessary for the ExternalizableLite interface). */ public ProfilerFilter() { } /** * Construct a ProfilerFilter for the specified filter. * * @param filter the filter to be profiled */ public ProfilerFilter(IndexAwareFilter filter) { m_filter = filter; } /** * Construct a ProfilerFilter for the specified filter. This constructor * is inteded only for internal use to profile filters returned by the * {@link IndexAwareFilter#applyIndex} method call. * * @param filter the filter to be profiled * @param cEvalSize initial entry set size for the underlying filter's * evalutation * @param ldtStart evaluation start timestamp */ protected ProfilerFilter(IndexAwareFilter filter, int cEvalSize, long ldtStart) { m_filter = filter; m_cEvalSize = cEvalSize; m_ldtStart = ldtStart; } // ----- Filter interface ----------------------------------------------- /** * {@inheritDoc} */ public boolean evaluate(Object o) { return m_filter.evaluate(o); } // ----- IndexAwareFilter interface ------------------------------------- /** * {@inheritDoc} */ public int calculateEffectiveness(Map mapIndexes, Set setKeys) { return m_filter.calculateEffectiveness(mapIndexes, setKeys); } /** * {@inheritDoc} */ public Filter applyIndex(Map mapIndexes, Set setKeys) { m_ldtStart = getSafeTimeMillis(); Filter filter = m_filter.applyIndex(mapIndexes, setKeys); // applyIndex didn't return null - further processing is required if (filter != null && s_fLogWarnings) { CacheFactory.log("Possibly missing an index for filter:" + m_filter, CacheFactory.LOG_WARN); filter = new ProfilerFilter((IndexAwareFilter)filter, setKeys.size(), m_ldtStart); } else if (s_fLogTimes) { CacheFactory.log("Filter " + m_filter + " execution time:" + (getSafeTimeMillis() - m_ldtStart)); } return filter; } // ----- EntryFilter interface ------------------------------------------ /** * {@inheritDoc} */ public boolean evaluateEntry(Map.Entry entry) { boolean bResult = m_filter.evaluateEntry(entry); if (s_fLogTimes && --m_cEvalSize == 0) { CacheFactory.log("Filter " + m_filter + " execution time:" + (getSafeTimeMillis() - m_ldtStart)); } return bResult; } // ----- Object methods ------------------------------------------------- /** * Return a human-readable description for this Filter. * * @return a String description of the Filter */ public String toString() { return "ProfilterFilter[filter=" + m_filter + "]"; } // ----- ExternalizableLite interface ----------------------------------- /** * {@inheritDoc} */ public void readExternal(DataInput in) throws IOException { m_filter = (IndexAwareFilter) ExternalizableHelper.readObject(in); } /** * {@inheritDoc} */ public void writeExternal(DataOutput out) throws IOException { ExternalizableHelper.writeObject(out, m_filter); } // ----- PortableObject interface --------------------------------------- /** * {@inheritDoc} */ public void readExternal(PofReader in) throws IOException { m_filter = (IndexAwareFilter) in.readObject(0); } /** * {@inheritDoc} */ public void writeExternal(PofWriter out) throws IOException { out.writeObject(0, m_filter); } // ----- data members --------------------------------------------------- /** * The filter which is being profiled. */ protected IndexAwareFilter m_filter; /** * Initial entry set size for the underlying filter's evaluation. */ transient private int m_cEvalSize = 0; /** * Time when an underlying filter evaluation started. */ transient private long m_ldtStart = 0; /** * Flag indicating to log missing index warnings. */ public static final boolean s_fLogWarnings = Boolean.parseBoolean(System.getProperty("coherence.profilerfilter.logwarnings")); /** * Flag indicating to log filter execution times. */ public static final boolean s_fLogTimes = Boolean.parseBoolean(System.getProperty("coherence.profilerfilter.logtimes")); }