1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.hadoop.hbase;
20  
21  import java.util.ArrayList;
22  import java.util.Comparator;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.NavigableSet;
26  import java.util.TreeMap;
27  import java.util.TreeSet;
28  
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  
31  
32  
33  
34  
35  
36  
37  @InterfaceAudience.Private
38  public class HDFSBlocksDistribution {
39    private Map<String,HostAndWeight> hostAndWeights = null;
40    private long uniqueBlocksTotalWeight = 0;
41  
42    
43  
44  
45  
46  
47  
48  
49  
50  
51  
52    public static class HostAndWeight {
53  
54      private String host;
55      private long weight;
56  
57      
58  
59  
60  
61  
62      public HostAndWeight(String host, long weight) {
63        this.host = host;
64        this.weight = weight;
65      }
66  
67      
68  
69  
70  
71      public void addWeight(long weight) {
72        this.weight += weight;
73      }
74  
75      
76  
77  
78      public String getHost() {
79        return host;
80      }
81  
82      
83  
84  
85      public long getWeight() {
86        return weight;
87      }
88  
89      
90  
91  
92      public static class WeightComparator implements Comparator<HostAndWeight> {
93        @Override
94        public int compare(HostAndWeight l, HostAndWeight r) {
95          if(l.getWeight() == r.getWeight()) {
96            return l.getHost().compareTo(r.getHost());
97          }
98          return l.getWeight() < r.getWeight() ? -1 : 1;
99        }
100     }
101   }
102 
103   
104 
105 
106   public HDFSBlocksDistribution() {
107     this.hostAndWeights =
108       new TreeMap<String,HostAndWeight>();
109   }
110 
111   
112 
113 
114   @Override
115   public synchronized String toString() {
116     return "number of unique hosts in the disribution=" +
117       this.hostAndWeights.size();
118   }
119 
120   
121 
122 
123 
124 
125   public void addHostsAndBlockWeight(String[] hosts, long weight) {
126     if (hosts == null || hosts.length == 0) {
127       
128       return;
129     }
130 
131     addUniqueWeight(weight);
132     for (String hostname : hosts) {
133       addHostAndBlockWeight(hostname, weight);
134     }
135   }
136 
137   
138 
139 
140 
141   private void addUniqueWeight(long weight) {
142     uniqueBlocksTotalWeight += weight;
143   }
144 
145 
146   
147 
148 
149 
150 
151   private void addHostAndBlockWeight(String host, long weight) {
152     if (host == null) {
153       
154       return;
155     }
156 
157     HostAndWeight hostAndWeight = this.hostAndWeights.get(host);
158     if(hostAndWeight == null) {
159       hostAndWeight = new HostAndWeight(host, weight);
160       this.hostAndWeights.put(host, hostAndWeight);
161     } else {
162       hostAndWeight.addWeight(weight);
163     }
164   }
165 
166   
167 
168 
169   public Map<String,HostAndWeight> getHostAndWeights() {
170     return this.hostAndWeights;
171   }
172 
173   
174 
175 
176 
177 
178 
179   public long getWeight(String host) {
180     long weight = 0;
181     if (host != null) {
182       HostAndWeight hostAndWeight = this.hostAndWeights.get(host);
183       if(hostAndWeight != null) {
184         weight = hostAndWeight.getWeight();
185       }
186     }
187     return weight;
188   }
189 
190   
191 
192 
193   public long getUniqueBlocksTotalWeight() {
194     return uniqueBlocksTotalWeight;
195   }
196 
197   
198 
199 
200 
201 
202   public float getBlockLocalityIndex(String host) {
203     float localityIndex = 0;
204     HostAndWeight hostAndWeight = this.hostAndWeights.get(host);
205     if (hostAndWeight != null && uniqueBlocksTotalWeight != 0) {
206       localityIndex=(float)hostAndWeight.weight/(float)uniqueBlocksTotalWeight;
207     }
208     return localityIndex;
209   }
210 
211 
212   
213 
214 
215 
216   public void add(HDFSBlocksDistribution otherBlocksDistribution) {
217     Map<String,HostAndWeight> otherHostAndWeights =
218       otherBlocksDistribution.getHostAndWeights();
219     for (Map.Entry<String, HostAndWeight> otherHostAndWeight:
220       otherHostAndWeights.entrySet()) {
221       addHostAndBlockWeight(otherHostAndWeight.getValue().host,
222         otherHostAndWeight.getValue().weight);
223     }
224     addUniqueWeight(otherBlocksDistribution.getUniqueBlocksTotalWeight());
225   }
226 
227   
228 
229 
230   public List<String> getTopHosts() {
231     HostAndWeight[] hostAndWeights = getTopHostsWithWeights();
232     List<String> topHosts = new ArrayList<String>(hostAndWeights.length);
233     for(HostAndWeight haw : hostAndWeights) {
234       topHosts.add(haw.getHost());
235     }
236     return topHosts;
237   }
238 
239   
240 
241 
242   public HostAndWeight[] getTopHostsWithWeights() {
243     NavigableSet<HostAndWeight> orderedHosts = new TreeSet<HostAndWeight>(
244       new HostAndWeight.WeightComparator());
245     orderedHosts.addAll(this.hostAndWeights.values());
246     return orderedHosts.descendingSet().toArray(new HostAndWeight[orderedHosts.size()]);
247   }
248 
249 }