```java

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 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); } }