package algorithm.loadbalance;
import com.alibaba.fastjson.JSON;
import java.util.*;
/**
* @author Cao Xuan
* @date 2021/3/21 20:04
* @update 2021/5/5
*/
public class LoadBalanceDemo {
private final List<Server> serverList = new ArrayList<>();
/**
* client -> server
*/
private final Map<Client, Server> clientServerMap = new HashMap<>();
/**
* <---head---tail--->
* <---light---weight--->
* <---former---latter-->
*/
@Deprecated
private void sort() {
for (int i = serverList.size() - 1; i > 0; i--) {
for (int j = i - 1; j > -1; j--) {
Server latter = new Server(serverList.get(i));
Server former = new Server(serverList.get(j));
if (latter.getCurrentLoad().size() > former.getCurrentLoad().size()) {
serverList.set(i, former);
serverList.set(j, latter);
}
}
}
System.out.println("sorting...");
}
/**
* <---head---tail--->
* <---light---weight--->
* <---former---latter-->
*/
private void leafShift() {
int size = serverList.size();
for (int i = size - 2; i >= 0; i--) {
Server latter = new Server(serverList.get(size - 1));
Server former = new Server(serverList.get(i));
if (latter.getCurrentLoad().size() > former.getCurrentLoad().size()) {
serverList.set(size - 1, former);
serverList.set(i, latter);
System.out.println("leaf shift");
}
}
}
private void rightShift(int index) {
int size = serverList.size();
for (int i = index + 1; i < size; i++) {
Server former = new Server(serverList.get(index));
Server latter = new Server(serverList.get(i));
if (former.getCurrentLoad().size() < latter.getCurrentLoad().size()) {
serverList.set(i, former);
serverList.set(index, latter);
System.out.println("right shift");
}
}
}
public Server addClient(Client client) {
if (serverList.size() > 0) {
Server server = new Server(serverList.get(serverList.size() - 1));
String serverName = server.getName();
serverList.get(serverList.size() - 1).updateCurrentLoad(client);
System.out.println("Hi,[" + client.getUsername() + "]. Assign [" + serverName + "] to you");
leafShift();
show();
return server;
} else {
System.err.println("no server");
return null;
}
}
public void removeClient(String clientName) {
Server server = clientServerMap.get(new Client(clientName));
int index = serverList.indexOf(server);
if (-1 != index) {
server.currentLoad.remove(new Client(clientName));
rightShift(index);
System.out.println("remove a client [" + clientName + "]");
} else {
System.err.println("index = -1");
}
show();
}
public void addServer(String name) {
Server server = new Server(name, new HashSet<>());
if (serverList.contains(server)) {
System.err.println("The server [" + name + "] already exists");
show();
return;
}
serverList.add(server);
System.out.println("add a server [" + name + "]");
show();
}
public void removeServer(String serverName) {
serverList.remove(new Server(serverName));
System.out.println("add a server [" + serverName + "]");
show();
}
private static class Client {
private String username;
public Client(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Client)) {
return false;
}
Client client = (Client) obj;
return this.getUsername().equals(client.getUsername());
}
@Override
public int hashCode() {
return Objects.hash(username);
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
private static class Server {
private String name;
private Set<Client> currentLoad;
public Server(String name) {
this.name = name;
}
public Server(Server server) {
this.name = server.name;
this.currentLoad = server.currentLoad;
}
public Server(String name, Set<Client> currentLoad) {
this.name = name;
this.currentLoad = currentLoad;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Client> getCurrentLoad() {
return currentLoad;
}
public void setCurrentLoad(Set<Client> currentLoad) {
this.currentLoad = currentLoad;
}
public void updateCurrentLoad(Client client) {
this.currentLoad.add(client);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Server)) {
return false;
}
Server server = (Server) obj;
return this.getName().equals(server.getName());
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
public static void main(String[] args) {
LoadBalanceDemo loadBalanceDemo = new LoadBalanceDemo();
System.out.println("---------------USAGE--------------");
System.out.println("Add a server: [s+${serverName}]");
System.out.println("Add a client: [c+${clientName}]");
System.out.println("Remove a server: [s-${serverName}]");
System.out.println("Remove a client: [c-${clientName}]");
System.out.println("Show Current Load: [show]");
System.out.println("---------------USAGE--------------");
while (true) {
System.out.println("ready");
System.out.println();
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
if ("show".equals(s)) {
loadBalanceDemo.show();
} else if (s.startsWith("c+")) {
String clientName = s.substring(2);
Client client = new Client(clientName);
Server server = loadBalanceDemo.addClient(client);
loadBalanceDemo.clientServerMap.put(client, server);
} else if (s.startsWith("s+")) {
String serverName = s.substring(2);
loadBalanceDemo.addServer(serverName);
} else if (s.startsWith("c-")) {
String clientName = s.substring(2);
loadBalanceDemo.removeClient(clientName);
} else if (s.startsWith("s-")) {
String serverName = s.substring(2);
loadBalanceDemo.removeServer(serverName);
} else {
System.out.println("?");
}
System.out.println("----------------------------------");
}
}
private void show() {
System.out.println("current load " + serverList);
}
}