• [LintCode] Load Balancer


    Implement a load balancer for web servers. It provide the following functionality:

    1. Add a new server to the cluster => add(server_id).
    2. Remove a bad server from the cluster => remove(server_id).
    3. Pick a server in the cluster randomly with equal probability => pick().
    Example

    At beginning, the cluster is empty => {}.

    add(1)
    add(2)
    add(3)
    pick()
    >> 1         // the return value is random, it can be either 1, 2, or 3.
    pick()
    >> 2
    pick()
    >> 1
    pick()
    >> 3
    remove(1)
    pick()
    >> 2
    pick()
    >> 3
    pick()
    >> 3

    Analysis
    To implement add/remove server id in O(1), we can only use hash map. However, it is not easy to
    implement pick randomly.

    Using array will be easy to implement pick random method. But using array alone does not give us O(1) remove operation.
    Instead, we get a O(n) remove.

    The solution is to use both a hash map and an arraylist to get O(1) add/remove/pick operations. 

    The arraylist stores all server ids and the hash map maps server id to its index in the arraylist. 

    Add:  add a new server id to the end of the arraylist; add a new key value pair for this newly added server id in the hashmap.

    Remove:  Get the arraylist index of the server to be removed from the hash map, then remove the key value pair.

          Swap the server id at the end of the arraylist with the server id that is to be removed.

          Update the arraylist index of the swapped server id in the hash map. 

          Remove the server index at the end of the arraylist.

    Pick:  use rand to randomly pick a arraylist index.

    The key points of the above solution are:

    1. To achieve O(1) deletion in the arraylist,

    swap the element that needs to be removed with the last element, then delete the last element.

    2. To achieve O(1) lookup of which server id to remove in the arraylist,

    store a server id to arraylist index mapping in the hashmap.

     
     1 public class LoadBalancer {
     2     private HashMap<Integer, Integer> map;
     3     private ArrayList<Integer> list;
     4     private Random rand;
     5     public LoadBalancer() {
     6         this.map = new HashMap<Integer, Integer>();
     7         this.list = new ArrayList<Integer>();
     8         this.rand = new Random();
     9     }
    10 
    11     // @param server_id add a new server to the cluster 
    12     // @return void
    13     public void add(int server_id) {
    14         if(!map.containsKey(server_id)){
    15             list.add(server_id);
    16             map.put(server_id, list.size() - 1);    
    17         }
    18     }
    19 
    20     // @param server_id server_id remove a bad server from the cluster
    21     // @return void
    22     public void remove(int server_id) {
    23         if(map.containsKey(server_id)){
    24             int removeIdx = map.get(server_id);
    25             map.remove(server_id);
    26             int affectedServerId = list.get(list.size() - 1);
    27             map.put(affectedServerId, removeIdx);
    28             list.set(removeIdx, affectedServerId);
    29             list.remove(list.size() - 1);
    30         }
    31     }
    32 
    33     // @return pick a server in the cluster randomly with equal probability
    34     public int pick() {
    35         if(list.size() == 0){
    36             return -1;
    37         }
    38         int rand_idx = rand.nextInt(list.size());
    39         return list.get(rand_idx);
    40     } 
    41 }
     
  • 相关阅读:
    统计MySQL数据库硬盘占用量大小
    zookeeper 集群安装与配置
    On Java 8中文版 英雄召集令
    下划线参数转成驼峰
    在Ubuntu 18.04中安装JDK 8
    GIT和GitHub的使用总结
    Python目录
    selenium代码实例
    Fiddler请求图标含义
    Tensorflow之神经网络
  • 原文地址:https://www.cnblogs.com/lz87/p/7203653.html
Copyright © 2020-2023  润新知