View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.master.balancer;
20  
21  import java.util.List;
22  import java.util.Map;
23  import java.util.concurrent.ConcurrentHashMap;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.hbase.HRegionInfo;
29  import org.apache.hadoop.hbase.ServerName;
30  
31  /**
32   * This class contains the mapping information between each region and
33   * its favored region server list. Used by {@link FavoredNodeLoadBalancer} set
34   * of classes and from unit tests (hence the class is public)
35   *
36   * All the access to this class is thread-safe.
37   */
38  @InterfaceAudience.Private
39  public class FavoredNodesPlan {
40    private static final Log LOG = LogFactory.getLog(
41        FavoredNodesPlan.class.getName());
42  
43    /** the map between each region and its favored region server list */
44    private Map<HRegionInfo, List<ServerName>> favoredNodesMap;
45  
46    public static enum Position {
47      PRIMARY,
48      SECONDARY,
49      TERTIARY;
50    };
51  
52    public FavoredNodesPlan() {
53      favoredNodesMap = new ConcurrentHashMap<HRegionInfo, List<ServerName>>();
54    }
55  
56    /**
57     * Add an assignment to the plan
58     * @param region
59     * @param servers
60     */
61    public synchronized void updateFavoredNodesMap(HRegionInfo region,
62        List<ServerName> servers) {
63      if (region == null || servers == null || servers.size() ==0)
64        return;
65      this.favoredNodesMap.put(region, servers);
66    }
67  
68    /**
69     * @param region
70     * @return the list of favored region server for this region based on the plan
71     */
72    public synchronized List<ServerName> getFavoredNodes(HRegionInfo region) {
73      return favoredNodesMap.get(region);
74    }
75  
76    /**
77     * Return the position of the server in the favoredNodes list. Assumes the
78     * favoredNodes list is of size 3.
79     * @param favoredNodes
80     * @param server
81     * @return position
82     */
83    public static Position getFavoredServerPosition(
84        List<ServerName> favoredNodes, ServerName server) {
85      if (favoredNodes == null || server == null ||
86          favoredNodes.size() != FavoredNodeAssignmentHelper.FAVORED_NODES_NUM) {
87        return null;
88      }
89      for (Position p : Position.values()) {
90        if (ServerName.isSameHostnameAndPort(favoredNodes.get(p.ordinal()),server)) {
91          return p;
92        }
93      }
94      return null;
95    }
96  
97    /**
98     * @return the mapping between each region to its favored region server list
99     */
100   public synchronized Map<HRegionInfo, List<ServerName>> getAssignmentMap() {
101     return this.favoredNodesMap;
102   }
103 
104   /**
105    * Add an assignment to the plan
106    * @param region
107    * @param servers
108    */
109   public synchronized void updateAssignmentPlan(HRegionInfo region,
110       List<ServerName> servers) {
111     if (region == null || servers == null || servers.size() ==0)
112       return;
113     this.favoredNodesMap.put(region, servers);
114     LOG.info("Update the assignment plan for region " +
115         region.getRegionNameAsString() + " ; favored nodes " +
116         FavoredNodeAssignmentHelper.getFavoredNodesAsString(servers));
117   }
118 
119   @Override
120   public boolean equals(Object o) {
121     if (this == o) {
122       return true;
123     }
124     if (o == null) {
125       return false;
126     }
127     if (getClass() != o.getClass()) {
128       return false;
129     }
130     // To compare the map from objec o is identical to current assignment map.
131     Map<HRegionInfo, List<ServerName>> comparedMap=
132       ((FavoredNodesPlan)o).getAssignmentMap();
133 
134     // compare the size
135     if (comparedMap.size() != this.favoredNodesMap.size())
136       return false;
137 
138     // compare each element in the assignment map
139     for (Map.Entry<HRegionInfo, List<ServerName>> entry :
140       comparedMap.entrySet()) {
141       List<ServerName> serverList = this.favoredNodesMap.get(entry.getKey());
142       if (serverList == null && entry.getValue() != null) {
143         return false;
144       } else if (serverList != null && !serverList.equals(entry.getValue())) {
145         return false;
146       }
147     }
148     return true;
149   }
150 
151   @Override
152   public int hashCode() {
153     return favoredNodesMap.hashCode();
154   }
155 }