优化ClientAddress

This commit is contained in:
Redkale
2023-01-06 15:16:58 +08:00
parent 7ce7c71163
commit 158ea68265
2 changed files with 60 additions and 18 deletions

View File

@@ -108,6 +108,7 @@ public abstract class Client<R extends ClientRequest, P> {
if (maxPipelines < 1) { if (maxPipelines < 1) {
throw new IllegalArgumentException("maxPipelines must bigger 0"); throw new IllegalArgumentException("maxPipelines must bigger 0");
} }
address.checkValid();
this.group = group; this.group = group;
this.tcp = tcp; this.tcp = tcp;
this.address = address; this.address = address;

View File

@@ -46,9 +46,18 @@ public class ClientAddress implements java.io.Serializable {
return this; return this;
} }
public void updateWeightAddress(List<WeightAddress> addrs) { public void updateAddress(SocketAddress addr, List<WeightAddress> addrs) {
this.weights = new ArrayList<>(addrs); if (addr == null && (addrs == null || addrs.isEmpty())) {
this.addresses = null; throw new NullPointerException("address is empty");
}
setWeights(addrs);
setAddress(addr);
}
public void checkValid() {
if (address == null && (weights == null || weights.isEmpty())) {
throw new NullPointerException("address is empty");
}
} }
public CompletableFuture<AsyncConnection> createClient(final boolean tcp, final AsyncGroup group, int readTimeoutSeconds, int writeTimeoutSeconds) { public CompletableFuture<AsyncConnection> createClient(final boolean tcp, final AsyncGroup group, int readTimeoutSeconds, int writeTimeoutSeconds) {
@@ -58,21 +67,8 @@ public class ClientAddress implements java.io.Serializable {
if (addrs == null) { if (addrs == null) {
synchronized (this) { synchronized (this) {
if (this.addresses == null) { if (this.addresses == null) {
int size = 0; this.addresses = createAddressArray(this.weights);
List<WeightAddress> ws = this.weights; addrs = this.addresses;
for (WeightAddress w : ws) {
size += w.getWeight();
}
SocketAddress[] newAddrs = new SocketAddress[size];
int index = -1;
for (int i = 0; i < ws.size(); i++) {
WeightAddress w = ws.get(i);
for (int j = 0; j < w.getWeight(); j++) {
newAddrs[++index] = w.getAddress();
}
}
addrs = newAddrs;
this.addresses = newAddrs;
} }
} }
} }
@@ -81,6 +77,42 @@ public class ClientAddress implements java.io.Serializable {
return group.createClient(tcp, addr, readTimeoutSeconds, writeTimeoutSeconds); return group.createClient(tcp, addr, readTimeoutSeconds, writeTimeoutSeconds);
} }
private static SocketAddress[] createAddressArray(List<WeightAddress> ws) {
int min = 0;
for (WeightAddress w : ws) {
if (min == 0 || w.getWeight() < min) {
min = w.getWeight();
}
}
int divisor = 1; //最大公约数
for (int i = 2; i <= min; i++) {
boolean all = true;
for (WeightAddress w : ws) {
if (w.getWeight() % i > 0) {
all = false;
break;
}
}
if (all) {
divisor = i;
}
}
int size = 0; //20,35,45去掉最大公约数数组长度为:4+7+9=20
for (WeightAddress w : ws) {
size += w.getWeight() / divisor;
}
SocketAddress[] newAddrs = new SocketAddress[size];
int index = -1;
for (int i = 0; i < ws.size(); i++) {
WeightAddress w = ws.get(i);
int z = w.getWeight() / divisor;
for (int j = 0; j < z; j++) {
newAddrs[++index] = w.getAddress();
}
}
return newAddrs;
}
public SocketAddress getAddress() { public SocketAddress getAddress() {
return address; return address;
} }
@@ -89,6 +121,15 @@ public class ClientAddress implements java.io.Serializable {
this.address = address; this.address = address;
} }
public List<WeightAddress> getWeights() {
return weights;
}
public void setWeights(List<WeightAddress> weights) {
this.weights = weights == null ? null : new ArrayList<>(weights);
this.addresses = null;
}
@Override @Override
public String toString() { public String toString() {
return JsonConvert.root().convertTo(this); return JsonConvert.root().convertTo(this);