diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java index 312a3ae..a2a87e6 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java @@ -32,6 +32,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -80,6 +81,12 @@ public abstract class CoprocessorHost { /** Ordered set of loaded coprocessors with lock */ protected SortedSet coprocessors = new SortedCopyOnWriteSet(new EnvironmentPriorityComparator()); + /** + * List of coprocessors to iterate over w/o creation of an iterator object. + * This list is always in sync with above coprocessor set ('coprocessors'). + * + **/ + protected AtomicReference> coprocessorList = new AtomicReference>(); protected Configuration conf; // unique file prefix to use for local copies of jars when classloading protected String pathPrefix; @@ -90,6 +97,16 @@ public abstract class CoprocessorHost { this.pathPrefix = UUID.randomUUID().toString(); } + protected void updateCoprocessorList() + { + List newList = new ArrayList(); + for(E env: coprocessors) + { + newList.add(env); + } + this.coprocessorList.set(newList); + } + /** * Not to be confused with the per-object _coprocessors_ (above), * coprocessorNames is static and stores the set of all coprocessors ever @@ -210,6 +227,7 @@ public abstract class CoprocessorHost { throws IOException { E env = loadInstance(implClass, priority, conf); coprocessors.add(env); + updateCoprocessorList(); } /** @@ -546,6 +564,7 @@ public abstract class CoprocessorHost { LOG.error("Removing coprocessor '" + env.toString() + "' from " + "environment because it threw: " + e,e); coprocessors.remove(env); + updateCoprocessorList(); try { shutdown(env); } catch (Exception x) { diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java index 87c8b9e..545c6df 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java @@ -230,6 +230,7 @@ public class RegionCoprocessorHost // load Coprocessor From HDFS loadTableCoprocessors(conf); + updateCoprocessorList(); } static List getTableCoprocessorAttrsFromSchema(Configuration conf, @@ -1720,7 +1721,9 @@ public class RegionCoprocessorHost private boolean execOperation(final boolean earlyExit, final CoprocessorOperation ctx) throws IOException { boolean bypass = false; - for (RegionEnvironment env: coprocessors) { + List list = this.coprocessorList.get(); + for (int i=0; i < list.size(); i++) { + RegionEnvironment env = list.get(i); Coprocessor observer = env.getInstance(); if (ctx.hasCall(observer)) { long startTime = System.nanoTime(); diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALCoprocessorHost.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALCoprocessorHost.java index 52dcee0..c9e47b5 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALCoprocessorHost.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALCoprocessorHost.java @@ -21,13 +21,13 @@ package org.apache.hadoop.hbase.regionserver.wal; import java.io.IOException; +import java.util.List; import org.apache.hadoop.hbase.Coprocessor; import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.coprocessor.*; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; - import org.apache.hadoop.hbase.wal.WAL; import org.apache.hadoop.hbase.wal.WALKey; @@ -98,6 +98,7 @@ public class WALCoprocessorHost this.wal = log; // load system default cp's from configuration. loadSystemCoprocessors(conf, WAL_COPROCESSOR_CONF_KEY); + updateCoprocessorList(); } @Override @@ -120,7 +121,9 @@ public class WALCoprocessorHost boolean bypass = false; if (this.coprocessors == null || this.coprocessors.isEmpty()) return bypass; ObserverContext ctx = null; - for (WALEnvironment env: coprocessors) { + List list = this.coprocessorList.get(); + for (int i=0; i < list.size(); i++) { + WALEnvironment env = list.get(i); if (env.getInstance() instanceof WALObserver) { final WALObserver observer = (WALObserver)env.getInstance(); ctx = ObserverContext.createAndPrepare(env, ctx); @@ -162,8 +165,10 @@ public class WALCoprocessorHost throws IOException { if (this.coprocessors == null || this.coprocessors.isEmpty()) return; ObserverContext ctx = null; - for (WALEnvironment env: coprocessors) { - if (env.getInstance() instanceof WALObserver) { + List list = this.coprocessorList.get(); + for (int i=0; i < list.size(); i++) { + WALEnvironment env = list.get(i); + if (env.getInstance() instanceof WALObserver) { final WALObserver observer = (WALObserver)env.getInstance(); ctx = ObserverContext.createAndPrepare(env, ctx); Thread currentThread = Thread.currentThread();