001/** 002* 003* Licensed to the Apache Software Foundation (ASF) under one 004* or more contributor license agreements. See the NOTICE file 005* distributed with this work for additional information 006* regarding copyright ownership. The ASF licenses this file 007* to you under the Apache License, Version 2.0 (the 008* "License"); you may not use this file except in compliance 009* with the License. You may obtain a copy of the License at 010* 011* http://www.apache.org/licenses/LICENSE-2.0 012* 013* Unless required by applicable law or agreed to in writing, software 014* distributed under the License is distributed on an "AS IS" BASIS, 015* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016* See the License for the specific language governing permissions and 017* limitations under the License. 018*/ 019package org.apache.hadoop.hbase.client; 020 021import java.io.IOException; 022import java.util.ArrayList; 023import java.util.Arrays; 024import java.util.Collections; 025import java.util.List; 026import org.apache.hadoop.hbase.HConstants; 027import org.apache.hadoop.hbase.HRegionLocation; 028import org.apache.hadoop.hbase.MetaTableAccessor; 029import org.apache.hadoop.hbase.RegionLocations; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.yetus.audience.InterfaceAudience; 032 033/** 034 * An implementation of {@link RegionLocator}. Used to view region location information for a single 035 * HBase table. Lightweight. Get as needed and just close when done. Instances of this class SHOULD 036 * NOT be constructed directly. Obtain an instance via {@link Connection}. See 037 * {@link ConnectionFactory} class comment for an example of how. 038 * <p/> 039 * This class is thread safe 040 */ 041@InterfaceAudience.Private 042public class HRegionLocator implements RegionLocator { 043 044 private final TableName tableName; 045 private final ConnectionImplementation connection; 046 047 public HRegionLocator(TableName tableName, ConnectionImplementation connection) { 048 this.connection = connection; 049 this.tableName = tableName; 050 } 051 052 /** 053 * {@inheritDoc} 054 */ 055 @Override 056 public void close() throws IOException { 057 // This method is required by the RegionLocator interface. This implementation does not have any 058 // persistent state, so there is no need to do anything here. 059 } 060 061 @Override 062 public HRegionLocation getRegionLocation(byte[] row, int replicaId, boolean reload) 063 throws IOException { 064 return connection.locateRegion(tableName, row, !reload, true, replicaId) 065 .getRegionLocation(replicaId); 066 } 067 068 @Override 069 public List<HRegionLocation> getRegionLocations(byte[] row, boolean reload) throws IOException { 070 RegionLocations locs = 071 connection.locateRegion(tableName, row, !reload, true, RegionInfo.DEFAULT_REPLICA_ID); 072 return Arrays.asList(locs.getRegionLocations()); 073 } 074 075 @Override 076 public List<HRegionLocation> getAllRegionLocations() throws IOException { 077 ArrayList<HRegionLocation> regions = new ArrayList<>(); 078 for (RegionLocations locations : listRegionLocations()) { 079 for (HRegionLocation location : locations.getRegionLocations()) { 080 regions.add(location); 081 } 082 connection.cacheLocation(tableName, locations); 083 } 084 return regions; 085 } 086 087 @Override 088 public void clearRegionLocationCache() { 089 connection.clearRegionCache(tableName); 090 } 091 092 @Override 093 public TableName getName() { 094 return this.tableName; 095 } 096 097 private List<RegionLocations> listRegionLocations() throws IOException { 098 if (TableName.isMetaTableName(tableName)) { 099 return Collections 100 .singletonList(connection.locateRegion(tableName, HConstants.EMPTY_START_ROW, false, true)); 101 } 102 final List<RegionLocations> regions = new ArrayList<>(); 103 MetaTableAccessor.Visitor visitor = new MetaTableAccessor.TableVisitorBase(tableName) { 104 @Override 105 public boolean visitInternal(Result result) throws IOException { 106 RegionLocations locations = MetaTableAccessor.getRegionLocations(result); 107 if (locations == null) { 108 return true; 109 } 110 regions.add(locations); 111 return true; 112 } 113 }; 114 MetaTableAccessor.scanMetaForTableRegions(connection, visitor, tableName); 115 return regions; 116 } 117}