Index: src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java (revision 1552885) +++ src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java (working copy) @@ -50,6 +50,7 @@ import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver; import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; @@ -78,6 +79,7 @@ // The shared data map private static ReferenceMap sharedDataMap = new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK); + private final boolean hasCustomPostScannerFilterRow; /** * Encapsulation of the environment of each coprocessor @@ -153,6 +155,34 @@ // load Coprocessor From HDFS loadTableCoprocessors(conf); + + boolean hasCustomPostScannerFilterRow = false; + out: for (RegionEnvironment env: coprocessors) { + if (env.getInstance() instanceof RegionObserver) { + Class clazz = env.getInstance().getClass(); + for(;;) { + if (clazz == null) { + // we must have directly implemented RegionObserver + hasCustomPostScannerFilterRow = true; + break out; + } + if (clazz == BaseRegionObserver.class) { + // we reached BaseRegionObserver, try next coprocessor + break; + } + try { + clazz.getDeclaredMethod("postScannerFilterRow", ObserverContext.class, + InternalScanner.class, byte[].class, boolean.class); + // this coprocessor has a custom version of postScannerFilterRow + hasCustomPostScannerFilterRow = true; + break out; + } catch (NoSuchMethodException ignore) { + } + clazz = clazz.getSuperclass(); + } + } + } + this.hasCustomPostScannerFilterRow = hasCustomPostScannerFilterRow; } void loadTableCoprocessors(final Configuration conf) { @@ -1395,6 +1425,8 @@ */ public boolean postScannerFilterRow(final InternalScanner s, final byte[] currentRow) throws IOException { + // short circuit for performance + if (!hasCustomPostScannerFilterRow) return true; boolean hasMore = true; // By default assume more rows there. ObserverContext ctx = null; for (RegionEnvironment env : coprocessors) {