提交 9b7b1364 编写于 作者: N Nicolas De Loof

use a Builder to create ConsistentHash<Node>

invoking add(Node, replica) for all nodes rebuild the internal Table many times. Using a builder, Table is only created (and sorted) once
also avoid creating a fresh new Hash object (java 8 lambdas, I miss you)
上级 66766953
...@@ -1073,16 +1073,18 @@ public class Queue extends ResourceController implements Saveable { ...@@ -1073,16 +1073,18 @@ public class Queue extends ResourceController implements Saveable {
private void makeBuildable(BuildableItem p) { private void makeBuildable(BuildableItem p) {
if(Jenkins.FLYWEIGHT_SUPPORT && p.task instanceof FlyweightTask && !ifBlockedByHudsonShutdown(p.task)) { if(Jenkins.FLYWEIGHT_SUPPORT && p.task instanceof FlyweightTask && !ifBlockedByHudsonShutdown(p.task)) {
ConsistentHash<Node> hash = new ConsistentHash<Node>(new Hash<Node>() {
public String hash(Node node) { ConsistentHash.Builder<Node> builder = new ConsistentHash.Builder<Node>(NODE_HASH);
return node.getNodeName();
}
});
Jenkins h = Jenkins.getInstance(); Jenkins h = Jenkins.getInstance();
// Even if master is configured with zero executors, we may need to run a flyweight task like MatrixProject on it. // Even if master is configured with zero executors, we may need to run a flyweight task like MatrixProject on it.
hash.add(h, Math.max(h.getNumExecutors()*100, 1)); builder.add(h, Math.max(h.getNumExecutors() * 100, 1));
for (Node n : h.getNodes())
hash.add(n, n.getNumExecutors()*100); for (Node n : h.getNodes()) {
builder.add(n, n.getNumExecutors() * 100);
}
ConsistentHash<Node> hash = builder.build();
Label lbl = p.getAssignedLabel(); Label lbl = p.getAssignedLabel();
for (Node n : hash.list(p.task.getFullDisplayName())) { for (Node n : hash.list(p.task.getFullDisplayName())) {
...@@ -1101,6 +1103,13 @@ public class Queue extends ResourceController implements Saveable { ...@@ -1101,6 +1103,13 @@ public class Queue extends ResourceController implements Saveable {
p.enter(this); p.enter(this);
} }
private static Hash<Node> NODE_HASH = new Hash<Node>() {
public String hash(Node node) {
return node.getNodeName();
}
};
private boolean makePending(BuildableItem p) { private boolean makePending(BuildableItem p) {
// LOGGER.info("Making "+p.task+" pending"); // REMOVE // LOGGER.info("Making "+p.task+" pending"); // REMOVE
p.isPending = true; p.isPending = true;
......
...@@ -201,13 +201,13 @@ public class ConsistentHash<T> { ...@@ -201,13 +201,13 @@ public class ConsistentHash<T> {
} }
public ConsistentHash(Hash<T> hash) { public ConsistentHash(Hash<T> hash) {
this(hash,100); this(hash, 100);
} }
public ConsistentHash(Hash<T> hash, int defaultReplication) { public ConsistentHash(Hash<T> hash, int defaultReplication) {
this.hash = hash; this.hash = hash;
this.defaultReplication = defaultReplication; this.defaultReplication = defaultReplication;
this.table = new Table(); // initial empty table refreshTable();
} }
public int countAllPoints() { public int countAllPoints() {
...@@ -244,7 +244,7 @@ public class ConsistentHash<T> { ...@@ -244,7 +244,7 @@ public class ConsistentHash<T> {
* Removes the node entirely. This is the same as {@code add(node,0)} * Removes the node entirely. This is the same as {@code add(node,0)}
*/ */
public void remove(T node) { public void remove(T node) {
add(node,0); add(node, 0);
} }
/** /**
...@@ -254,6 +254,11 @@ public class ConsistentHash<T> { ...@@ -254,6 +254,11 @@ public class ConsistentHash<T> {
* This is the only function that manipulates {@link #items}. * This is the only function that manipulates {@link #items}.
*/ */
public synchronized void add(T node, int replica) { public synchronized void add(T node, int replica) {
addInternal(node, replica);
refreshTable();
}
private void addInternal(T node, int replica) {
if(replica==0) { if(replica==0) {
items.remove(node); items.remove(node);
} else { } else {
...@@ -263,9 +268,13 @@ public class ConsistentHash<T> { ...@@ -263,9 +268,13 @@ public class ConsistentHash<T> {
points[i] = new Point(md5(seed+':'+i),node); points[i] = new Point(md5(seed+':'+i),node);
items.put(node,points); items.put(node,points);
} }
}
private void refreshTable() {
table = new Table(); table = new Table();
} }
/** /**
* Compresses a string into an integer with MD5. * Compresses a string into an integer with MD5.
*/ */
...@@ -335,4 +344,24 @@ public class ConsistentHash<T> { ...@@ -335,4 +344,24 @@ public class ConsistentHash<T> {
public Iterable<T> list(String queryPoint) { public Iterable<T> list(String queryPoint) {
return list(md5(queryPoint)); return list(md5(queryPoint));
} }
public static class Builder<T> {
final ConsistentHash<T> c;
public Builder(Hash hash) {
c = new ConsistentHash<T>(hash);
}
public Builder add(T node, int replica) {
c.addInternal(node, replica);
return this;
}
public ConsistentHash<T> build() {
c.refreshTable();
return c;
}
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册