001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.master.balancer;
019
020import java.util.List;
021import java.util.Map;
022import java.util.NavigableMap;
023import java.util.TreeMap;
024import org.apache.hadoop.hbase.ServerName;
025import org.apache.hadoop.hbase.client.RegionInfo;
026import org.apache.yetus.audience.InterfaceAudience;
027
028/**
029 * Class used to hold the current state of the cluster and how balanced it is.
030 */
031@InterfaceAudience.Private
032public class ClusterLoadState {
033  private final Map<ServerName, List<RegionInfo>> clusterState;
034  private final NavigableMap<ServerAndLoad, List<RegionInfo>> serversByLoad;
035  private boolean emptyRegionServerPresent = false;
036  private int numRegions = 0;
037  private int numServers = 0;
038
039  public ClusterLoadState(Map<ServerName, List<RegionInfo>> clusterState) {
040    this.numRegions = 0;
041    this.numServers = clusterState.size();
042    this.clusterState = clusterState;
043    serversByLoad = new TreeMap<>();
044    // Iterate so we can count regions as we build the map
045    for (Map.Entry<ServerName, List<RegionInfo>> server : clusterState.entrySet()) {
046      List<RegionInfo> regions = server.getValue();
047      int sz = regions.size();
048      if (sz == 0) emptyRegionServerPresent = true;
049      numRegions += sz;
050      serversByLoad.put(new ServerAndLoad(server.getKey(), sz), regions);
051    }
052  }
053
054  Map<ServerName, List<RegionInfo>> getClusterState() {
055    return clusterState;
056  }
057
058  NavigableMap<ServerAndLoad, List<RegionInfo>> getServersByLoad() {
059    return serversByLoad;
060  }
061
062  boolean isEmptyRegionServerPresent() {
063    return emptyRegionServerPresent;
064  }
065
066  int getNumRegions() {
067    return numRegions;
068  }
069
070  int getNumServers() {
071    return numServers;
072  }
073
074  float getLoadAverage() {
075    return (float) numRegions / numServers;
076  }
077
078  int getMaxLoad() {
079    return getServersByLoad().lastKey().getLoad();
080  }
081
082  int getMinLoad() {
083    return getServersByLoad().firstKey().getLoad();
084  }
085
086}