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; 019 020import java.io.DataInputStream; 021import java.io.IOException; 022import java.util.ArrayList; 023import java.util.Arrays; 024import java.util.List; 025import java.util.stream.Collectors; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.KeyValue.KVComparator; 028import org.apache.hadoop.hbase.client.RegionInfo; 029import org.apache.hadoop.hbase.client.RegionInfoBuilder; 030import org.apache.hadoop.hbase.client.RegionInfoDisplay; 031import org.apache.hadoop.hbase.exceptions.DeserializationException; 032import org.apache.hadoop.hbase.master.RegionState; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 035import org.apache.hadoop.io.DataInputBuffer; 036import org.apache.yetus.audience.InterfaceAudience; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 041import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 042 043/** 044 * Information about a region. A region is a range of keys in the whole keyspace of a table, an 045 * identifier (a timestamp) for differentiating between subset ranges (after region split) and a 046 * replicaId for differentiating the instance for the same range and some status information about 047 * the region. The region has a unique name which consists of the following fields: 048 * <ul> 049 * <li>tableName : The name of the table</li> 050 * <li>startKey : The startKey for the region.</li> 051 * <li>regionId : A timestamp when the region is created.</li> 052 * <li>replicaId : An id starting from 0 to differentiate replicas of the same region range but 053 * hosted in separated servers. The same region range can be hosted in multiple locations.</li> 054 * <li>encodedName : An MD5 encoded string for the region name.</li> 055 * </ul> 056 * <br> 057 * Other than the fields in the region name, region info contains: 058 * <ul> 059 * <li>endKey : the endKey for the region (exclusive)</li> 060 * <li>split : Whether the region is split</li> 061 * <li>offline : Whether the region is offline</li> 062 * </ul> 063 * In 0.98 or before, a list of table's regions would fully cover the total keyspace, and at any 064 * point in time, a row key always belongs to a single region, which is hosted in a single server. 065 * In 0.99+, a region can have multiple instances (called replicas), and thus a range (or row) can 066 * correspond to multiple HRegionInfo's. These HRI's share the same fields however except the 067 * replicaId field. If the replicaId is not set, it defaults to 0, which is compatible with the 068 * previous behavior of a range corresponding to 1 region. 069 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. use 070 * {@link RegionInfoBuilder} to build {@link RegionInfo}. 071 */ 072@Deprecated 073@InterfaceAudience.Public 074public class HRegionInfo implements RegionInfo { 075 private static final Logger LOG = LoggerFactory.getLogger(HRegionInfo.class); 076 077 /** 078 * The new format for a region name contains its encodedName at the end. The encoded name also 079 * serves as the directory name for the region in the filesystem. New region name format: 080 * <tablename>,,<startkey>,<regionIdTimestamp>.<encodedName>. where, <encodedName> 081 * is a hex version of the MD5 hash of <tablename>,<startkey>,<regionIdTimestamp> The old 082 * region name format: <tablename>,<startkey>,<regionIdTimestamp> For region names in the 083 * old format, the encoded name is a 32-bit JenkinsHash integer value (in its decimal notation, 084 * string form). 085 * <p> 086 * **NOTE** The first hbase:meta region, and regions created by an older version of HBase (0.20 or 087 * prior) will continue to use the old region name format. 088 */ 089 090 /** A non-capture group so that this can be embedded. */ 091 public static final String ENCODED_REGION_NAME_REGEX = 092 RegionInfoBuilder.ENCODED_REGION_NAME_REGEX; 093 094 private static final int MAX_REPLICA_ID = 0xFFFF; 095 096 /** 097 * n * @return the encodedName 098 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 099 * {@link org.apache.hadoop.hbase.client.RegionInfo#encodeRegionName(byte[])}. 100 */ 101 @Deprecated 102 public static String encodeRegionName(final byte[] regionName) { 103 return RegionInfo.encodeRegionName(regionName); 104 } 105 106 /** 107 * Returns Return a short, printable name for this region (usually encoded name) for us logging. 108 */ 109 @Override 110 public String getShortNameToLog() { 111 return prettyPrint(this.getEncodedName()); 112 } 113 114 /** 115 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 116 * {@link org.apache.hadoop.hbase.client.RegionInfo#getShortNameToLog(RegionInfo...)}. 117 */ 118 @Deprecated 119 public static String getShortNameToLog(HRegionInfo... hris) { 120 return RegionInfo.getShortNameToLog(Arrays.asList(hris)); 121 } 122 123 /** 124 * @return Return a String of short, printable names for <code>hris</code> (usually encoded name) 125 * for us logging. 126 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 127 * {@link org.apache.hadoop.hbase.client.RegionInfo#getShortNameToLog(List)})}. 128 */ 129 @Deprecated 130 public static String getShortNameToLog(final List<HRegionInfo> hris) { 131 return RegionInfo.getShortNameToLog(hris.stream().collect(Collectors.toList())); 132 } 133 134 /** 135 * Use logging. 136 * @param encodedRegionName The encoded regionname. 137 * @return <code>hbase:meta</code> if passed <code>1028785192</code> else returns 138 * <code>encodedRegionName</code> 139 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 140 * {@link RegionInfo#prettyPrint(String)}. 141 */ 142 @Deprecated 143 @InterfaceAudience.Private 144 public static String prettyPrint(final String encodedRegionName) { 145 return RegionInfo.prettyPrint(encodedRegionName); 146 } 147 148 private byte[] endKey = HConstants.EMPTY_BYTE_ARRAY; 149 // This flag is in the parent of a split while the parent is still referenced by daughter regions. 150 // We USED to set this flag when we disabled a table but now table state is kept up in zookeeper 151 // as of 0.90.0 HBase. And now in DisableTableProcedure, finally we will create bunch of 152 // UnassignProcedures and at the last of the procedure we will set the region state to CLOSED, and 153 // will not change the offLine flag. 154 private boolean offLine = false; 155 private long regionId = -1; 156 private transient byte[] regionName = HConstants.EMPTY_BYTE_ARRAY; 157 private boolean split = false; 158 private byte[] startKey = HConstants.EMPTY_BYTE_ARRAY; 159 private int hashCode = -1; 160 // TODO: Move NO_HASH to HStoreFile which is really the only place it is used. 161 public static final String NO_HASH = null; 162 private String encodedName = null; 163 private byte[] encodedNameAsBytes = null; 164 private int replicaId = DEFAULT_REPLICA_ID; 165 166 // Current TableName 167 private TableName tableName = null; 168 169 // Duplicated over in RegionInfoDisplay 170 final static String DISPLAY_KEYS_KEY = RegionInfoDisplay.DISPLAY_KEYS_KEY; 171 public final static byte[] HIDDEN_END_KEY = RegionInfoDisplay.HIDDEN_END_KEY; 172 public final static byte[] HIDDEN_START_KEY = RegionInfoDisplay.HIDDEN_START_KEY; 173 174 /** HRegionInfo for first meta region */ 175 // TODO: How come Meta regions still do not have encoded region names? Fix. 176 public static final HRegionInfo FIRST_META_REGIONINFO = 177 new HRegionInfo(1L, TableName.META_TABLE_NAME); 178 179 private void setHashCode() { 180 int result = Arrays.hashCode(this.regionName); 181 result = (int) (result ^ this.regionId); 182 result ^= Arrays.hashCode(this.startKey); 183 result ^= Arrays.hashCode(this.endKey); 184 result ^= Boolean.valueOf(this.offLine).hashCode(); 185 result ^= Arrays.hashCode(this.tableName.getName()); 186 result ^= this.replicaId; 187 this.hashCode = result; 188 } 189 190 /** 191 * Private constructor used constructing HRegionInfo for the first meta regions 192 */ 193 private HRegionInfo(long regionId, TableName tableName) { 194 this(regionId, tableName, DEFAULT_REPLICA_ID); 195 } 196 197 public HRegionInfo(long regionId, TableName tableName, int replicaId) { 198 super(); 199 this.regionId = regionId; 200 this.tableName = tableName; 201 this.replicaId = replicaId; 202 // Note: First Meta region replicas names are in old format 203 this.regionName = createRegionName(tableName, null, regionId, replicaId, false); 204 setHashCode(); 205 } 206 207 public HRegionInfo(final TableName tableName) { 208 this(tableName, null, null); 209 } 210 211 /** 212 * Construct HRegionInfo with explicit parameters 213 * @param tableName the table name 214 * @param startKey first key in region 215 * @param endKey end of key range n 216 */ 217 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey) 218 throws IllegalArgumentException { 219 this(tableName, startKey, endKey, false); 220 } 221 222 /** 223 * Construct HRegionInfo with explicit parameters 224 * @param tableName the table name 225 * @param startKey first key in region 226 * @param endKey end of key range 227 * @param split true if this region has split and we have daughter regions regions that may or 228 * may not hold references to this region. n 229 */ 230 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey, 231 final boolean split) throws IllegalArgumentException { 232 this(tableName, startKey, endKey, split, EnvironmentEdgeManager.currentTime()); 233 } 234 235 /** 236 * Construct HRegionInfo with explicit parameters 237 * @param tableName the table name 238 * @param startKey first key in region 239 * @param endKey end of key range 240 * @param split true if this region has split and we have daughter regions regions that may or 241 * may not hold references to this region. 242 * @param regionId Region id to use. 243 */ 244 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey, 245 final boolean split, final long regionId) throws IllegalArgumentException { 246 this(tableName, startKey, endKey, split, regionId, DEFAULT_REPLICA_ID); 247 } 248 249 /** 250 * Construct HRegionInfo with explicit parameters 251 * @param tableName the table name 252 * @param startKey first key in region 253 * @param endKey end of key range 254 * @param split true if this region has split and we have daughter regions regions that may or 255 * may not hold references to this region. 256 * @param regionId Region id to use. 257 * @param replicaId the replicaId to use 258 */ 259 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey, 260 final boolean split, final long regionId, final int replicaId) throws IllegalArgumentException { 261 super(); 262 if (tableName == null) { 263 throw new IllegalArgumentException("TableName cannot be null"); 264 } 265 this.tableName = tableName; 266 this.offLine = false; 267 this.regionId = regionId; 268 this.replicaId = replicaId; 269 if (this.replicaId > MAX_REPLICA_ID) { 270 throw new IllegalArgumentException("ReplicaId cannot be greater than" + MAX_REPLICA_ID); 271 } 272 273 this.regionName = createRegionName(this.tableName, startKey, regionId, replicaId, true); 274 275 this.split = split; 276 this.endKey = endKey == null ? HConstants.EMPTY_END_ROW : endKey.clone(); 277 this.startKey = startKey == null ? HConstants.EMPTY_START_ROW : startKey.clone(); 278 this.tableName = tableName; 279 setHashCode(); 280 } 281 282 /** 283 * Construct a copy of another HRegionInfo 284 */ 285 public HRegionInfo(RegionInfo other) { 286 super(); 287 this.endKey = other.getEndKey(); 288 this.offLine = other.isOffline(); 289 this.regionId = other.getRegionId(); 290 this.regionName = other.getRegionName(); 291 this.split = other.isSplit(); 292 this.startKey = other.getStartKey(); 293 this.hashCode = other.hashCode(); 294 this.encodedName = other.getEncodedName(); 295 this.tableName = other.getTable(); 296 this.replicaId = other.getReplicaId(); 297 } 298 299 public HRegionInfo(HRegionInfo other, int replicaId) { 300 this(other); 301 this.replicaId = replicaId; 302 this.setHashCode(); 303 } 304 305 /** 306 * Make a region name of passed parameters. 307 * @param tableName the table name 308 * @param startKey Can be null 309 * @param regionId Region id (Usually timestamp from when region was created). 310 * @param newFormat should we create the region name in the new format (such that it contains its 311 * encoded name?). 312 * @return Region name made of passed tableName, startKey and id 313 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 314 * {@link RegionInfo#createRegionName(TableName, byte[], long, boolean)}. 315 */ 316 @Deprecated 317 @InterfaceAudience.Private 318 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 319 final long regionId, boolean newFormat) { 320 return RegionInfo.createRegionName(tableName, startKey, Long.toString(regionId), newFormat); 321 } 322 323 /** 324 * Make a region name of passed parameters. 325 * @param tableName the table name 326 * @param startKey Can be null 327 * @param id Region id (Usually timestamp from when region was created). 328 * @param newFormat should we create the region name in the new format (such that it contains its 329 * encoded name?). 330 * @return Region name made of passed tableName, startKey and id 331 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 332 * {@link RegionInfo#createRegionName(TableName, byte[], String, boolean)}. 333 */ 334 @Deprecated 335 @InterfaceAudience.Private 336 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 337 final String id, boolean newFormat) { 338 return RegionInfo.createRegionName(tableName, startKey, Bytes.toBytes(id), newFormat); 339 } 340 341 /** 342 * Make a region name of passed parameters. 343 * @param tableName the table name 344 * @param startKey Can be null 345 * @param regionId Region id (Usually timestamp from when region was created). 346 * @param newFormat should we create the region name in the new format (such that it contains its 347 * encoded name?). 348 * @return Region name made of passed tableName, startKey, id and replicaId 349 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 350 * {@link RegionInfo#createRegionName(TableName, byte[], long, int, boolean)}. 351 */ 352 @Deprecated 353 @InterfaceAudience.Private 354 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 355 final long regionId, int replicaId, boolean newFormat) { 356 return RegionInfo.createRegionName(tableName, startKey, Bytes.toBytes(Long.toString(regionId)), 357 replicaId, newFormat); 358 } 359 360 /** 361 * Make a region name of passed parameters. 362 * @param tableName the table name 363 * @param startKey Can be null 364 * @param id Region id (Usually timestamp from when region was created). 365 * @param newFormat should we create the region name in the new format (such that it contains its 366 * encoded name?). 367 * @return Region name made of passed tableName, startKey and id 368 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 369 * {@link RegionInfo#createRegionName(TableName, byte[], byte[], boolean)}. 370 */ 371 @Deprecated 372 @InterfaceAudience.Private 373 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 374 final byte[] id, boolean newFormat) { 375 return RegionInfo.createRegionName(tableName, startKey, id, DEFAULT_REPLICA_ID, newFormat); 376 } 377 378 /** 379 * Make a region name of passed parameters. 380 * @param tableName the table name 381 * @param startKey Can be null 382 * @param id Region id (Usually timestamp from when region was created) 383 * @param newFormat should we create the region name in the new format 384 * @return Region name made of passed tableName, startKey, id and replicaId 385 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 386 * {@link RegionInfo#createRegionName(TableName, byte[], byte[], int, boolean)}. 387 */ 388 @Deprecated 389 @InterfaceAudience.Private 390 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 391 final byte[] id, final int replicaId, boolean newFormat) { 392 return RegionInfo.createRegionName(tableName, startKey, id, replicaId, newFormat); 393 } 394 395 /** 396 * Gets the table name from the specified region name. 397 * @param regionName to extract the table name from 398 * @return Table name 399 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 400 * {@link org.apache.hadoop.hbase.client.RegionInfo#getTable(byte[])}. 401 */ 402 @Deprecated 403 public static TableName getTable(final byte[] regionName) { 404 return RegionInfo.getTable(regionName); 405 } 406 407 /** 408 * Gets the start key from the specified region name. n * @return Start key. 409 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 410 * {@link org.apache.hadoop.hbase.client.RegionInfo#getStartKey(byte[])}. 411 */ 412 @Deprecated 413 public static byte[] getStartKey(final byte[] regionName) throws IOException { 414 return RegionInfo.getStartKey(regionName); 415 } 416 417 /** 418 * Separate elements of a regionName. n * @return Array of byte[] containing tableName, startKey 419 * and id n * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 420 * {@link RegionInfo#parseRegionName(byte[])}. 421 */ 422 @Deprecated 423 @InterfaceAudience.Private 424 public static byte[][] parseRegionName(final byte[] regionName) throws IOException { 425 return RegionInfo.parseRegionName(regionName); 426 } 427 428 /** 429 * n * @return if region name is encoded. n * @deprecated As of release 2.0.0, this will be 430 * removed in HBase 3.0.0 Use 431 * {@link org.apache.hadoop.hbase.client.RegionInfo#isEncodedRegionName(byte[])}. 432 */ 433 @Deprecated 434 public static boolean isEncodedRegionName(byte[] regionName) throws IOException { 435 return RegionInfo.isEncodedRegionName(regionName); 436 } 437 438 /** Returns the regionId */ 439 @Override 440 public long getRegionId() { 441 return regionId; 442 } 443 444 /** 445 * @return the regionName as an array of bytes. 446 * @see #getRegionNameAsString() 447 */ 448 @Override 449 public byte[] getRegionName() { 450 return regionName; 451 } 452 453 /** Returns Region name as a String for use in logging, etc. */ 454 @Override 455 public String getRegionNameAsString() { 456 if (RegionInfo.hasEncodedName(this.regionName)) { 457 // new format region names already have their encoded name. 458 return Bytes.toStringBinary(this.regionName); 459 } 460 461 // old format. regionNameStr doesn't have the region name. 462 // 463 // 464 return Bytes.toStringBinary(this.regionName) + "." + this.getEncodedName(); 465 } 466 467 /** Returns the encoded region name */ 468 @Override 469 public synchronized String getEncodedName() { 470 if (this.encodedName == null) { 471 this.encodedName = RegionInfo.encodeRegionName(this.regionName); 472 } 473 return this.encodedName; 474 } 475 476 @Override 477 public synchronized byte[] getEncodedNameAsBytes() { 478 if (this.encodedNameAsBytes == null) { 479 this.encodedNameAsBytes = Bytes.toBytes(getEncodedName()); 480 } 481 return this.encodedNameAsBytes; 482 } 483 484 /** Returns the startKey */ 485 @Override 486 public byte[] getStartKey() { 487 return startKey; 488 } 489 490 /** Returns the endKey */ 491 @Override 492 public byte[] getEndKey() { 493 return endKey; 494 } 495 496 /** 497 * Get current table name of the region n 498 */ 499 @Override 500 public TableName getTable() { 501 // This method name should be getTableName but there was already a method getTableName 502 // that returned a byte array. It is unfortunate given everywhere else, getTableName returns 503 // a TableName instance. 504 if (tableName == null || tableName.getName().length == 0) { 505 tableName = getTable(getRegionName()); 506 } 507 return this.tableName; 508 } 509 510 /** 511 * Returns true if the given inclusive range of rows is fully contained by this region. For 512 * example, if the region is foo,a,g and this is passed ["b","c"] or ["a","c"] it will return 513 * true, but if this is passed ["b","z"] it will return false. 514 * @throws IllegalArgumentException if the range passed is invalid (ie. end < start) 515 */ 516 @Override 517 public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) { 518 if (Bytes.compareTo(rangeStartKey, rangeEndKey) > 0) { 519 throw new IllegalArgumentException("Invalid range: " + Bytes.toStringBinary(rangeStartKey) 520 + " > " + Bytes.toStringBinary(rangeEndKey)); 521 } 522 523 boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) >= 0; 524 boolean lastKeyInRange = 525 Bytes.compareTo(rangeEndKey, endKey) < 0 || Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY); 526 return firstKeyInRange && lastKeyInRange; 527 } 528 529 /** Returns true if the given row falls in this region. */ 530 @Override 531 public boolean containsRow(byte[] row) { 532 return Bytes.compareTo(row, startKey) >= 0 533 && (Bytes.compareTo(row, endKey) < 0 || Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY)); 534 } 535 536 /** Returns true if this region is from hbase:meta */ 537 public boolean isMetaTable() { 538 return isMetaRegion(); 539 } 540 541 /** Returns true if this region is a meta region */ 542 @Override 543 public boolean isMetaRegion() { 544 return tableName.equals(HRegionInfo.FIRST_META_REGIONINFO.getTable()); 545 } 546 547 /** Returns true if this region is from a system table */ 548 public boolean isSystemTable() { 549 return tableName.isSystemTable(); 550 } 551 552 /** Returns true if has been split and has daughters. */ 553 @Override 554 public boolean isSplit() { 555 return this.split; 556 } 557 558 /** 559 * Set or clear the split status flag. 560 * @param split set split status 561 */ 562 public void setSplit(boolean split) { 563 this.split = split; 564 } 565 566 /** Returns true if this region is offline. */ 567 @Override 568 public boolean isOffline() { 569 return this.offLine; 570 } 571 572 /** 573 * The parent of a region split is offline while split daughters hold references to the parent. 574 * Offlined regions are closed. 575 * @param offLine Set online/offline status. 576 */ 577 public void setOffline(boolean offLine) { 578 this.offLine = offLine; 579 } 580 581 /** Returns true if this is a split parent region. */ 582 @Override 583 public boolean isSplitParent() { 584 if (!isSplit()) return false; 585 if (!isOffline()) { 586 LOG.warn("Region is split but NOT offline: " + getRegionNameAsString()); 587 } 588 return true; 589 } 590 591 /** 592 * Returns the region replica id 593 * @return returns region replica id 594 */ 595 @Override 596 public int getReplicaId() { 597 return replicaId; 598 } 599 600 /** 601 * @see java.lang.Object#toString() 602 */ 603 @Override 604 public String toString() { 605 return "{ENCODED => " + getEncodedName() + ", " + HConstants.NAME + " => '" 606 + Bytes.toStringBinary(this.regionName) + "', STARTKEY => '" 607 + Bytes.toStringBinary(this.startKey) + "', ENDKEY => '" + Bytes.toStringBinary(this.endKey) 608 + "'" + (isOffline() ? ", OFFLINE => true" : "") + (isSplit() ? ", SPLIT => true" : "") 609 + ((replicaId > 0) ? ", REPLICA_ID => " + replicaId : "") + "}"; 610 } 611 612 /** 613 * @see java.lang.Object#equals(java.lang.Object) 614 */ 615 @Override 616 public boolean equals(Object o) { 617 if (this == o) { 618 return true; 619 } 620 if (o == null) { 621 return false; 622 } 623 if (!(o instanceof HRegionInfo)) { 624 return false; 625 } 626 return this.compareTo((HRegionInfo) o) == 0; 627 } 628 629 /** 630 * @see java.lang.Object#hashCode() 631 */ 632 @Override 633 public int hashCode() { 634 return this.hashCode; 635 } 636 637 /** 638 * @return Comparator to use comparing {@link KeyValue}s. 639 * @deprecated Use Region#getCellComparator(). deprecated for hbase 2.0, remove for hbase 3.0 640 */ 641 @Deprecated 642 public KVComparator getComparator() { 643 return isMetaRegion() ? KeyValue.META_COMPARATOR : KeyValue.COMPARATOR; 644 } 645 646 /** 647 * Convert a HRegionInfo to the protobuf RegionInfo 648 * @return the converted RegionInfo 649 */ 650 HBaseProtos.RegionInfo convert() { 651 return convert(this); 652 } 653 654 /** 655 * Convert a HRegionInfo to a RegionInfo 656 * @param info the HRegionInfo to convert 657 * @return the converted RegionInfo 658 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 659 * toRegionInfo(org.apache.hadoop.hbase.client.RegionInfo) in 660 * org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil. 661 */ 662 @Deprecated 663 @InterfaceAudience.Private 664 public static HBaseProtos.RegionInfo convert(final HRegionInfo info) { 665 return ProtobufUtil.toRegionInfo(info); 666 } 667 668 /** 669 * Convert a RegionInfo to a HRegionInfo 670 * @param proto the RegionInfo to convert 671 * @return the converted HRegionInfo 672 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 673 * toRegionInfo(HBaseProtos.RegionInfo) in 674 * org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil. 675 */ 676 @Deprecated 677 @InterfaceAudience.Private 678 public static HRegionInfo convert(final HBaseProtos.RegionInfo proto) { 679 RegionInfo ri = ProtobufUtil.toRegionInfo(proto); 680 // This is hack of what is in RegionReplicaUtil but it is doing translation of 681 // RegionInfo into HRegionInfo which is what is wanted here. 682 HRegionInfo hri; 683 if (ri.isMetaRegion()) { 684 hri = ri.getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID 685 ? HRegionInfo.FIRST_META_REGIONINFO 686 : new HRegionInfo(ri.getRegionId(), ri.getTable(), ri.getReplicaId()); 687 } else { 688 hri = new HRegionInfo(ri.getTable(), ri.getStartKey(), ri.getEndKey(), ri.isSplit(), 689 ri.getRegionId(), ri.getReplicaId()); 690 if (proto.hasOffline()) { 691 hri.setOffline(proto.getOffline()); 692 } 693 } 694 return hri; 695 } 696 697 /** 698 * Serialize a {@link HRegionInfo} into a byte array. 699 * @return This instance serialized as protobuf w/ a magic pb prefix. 700 * @see #parseFrom(byte[]) 701 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 702 * {@link org.apache.hadoop.hbase.client.RegionInfo#toByteArray(RegionInfo)}. 703 */ 704 @Deprecated 705 public byte[] toByteArray() { 706 return RegionInfo.toByteArray(this); 707 } 708 709 /** 710 * Parse a serialized representation of a {@link HRegionInfo}. 711 * @return A deserialized {@link HRegionInfo} or null if we failed deserialize or passed bytes 712 * null 713 * @see #toByteArray() 714 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 715 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFromOrNull(byte[])}. 716 */ 717 @Deprecated 718 public static HRegionInfo parseFromOrNull(final byte[] bytes) { 719 if (bytes == null) return null; 720 return parseFromOrNull(bytes, 0, bytes.length); 721 } 722 723 /** 724 * Parse a serialized representation of a {@link HRegionInfo}. 725 * @return A deserialized {@link HRegionInfo} or null if we failed deserialize or passed bytes 726 * null 727 * @see #toByteArray() 728 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 729 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFromOrNull(byte[], int, int)}. 730 */ 731 @Deprecated 732 public static HRegionInfo parseFromOrNull(final byte[] bytes, int offset, int len) { 733 if (bytes == null || len <= 0) return null; 734 try { 735 return parseFrom(bytes, offset, len); 736 } catch (DeserializationException e) { 737 return null; 738 } 739 } 740 741 /** 742 * Parse a serialized representation of a {@link HRegionInfo}. 743 * @param bytes A pb RegionInfo serialized with a pb magic prefix. 744 * @return A deserialized {@link HRegionInfo} n * @see #toByteArray() 745 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 746 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFrom(byte[])}. 747 */ 748 public static HRegionInfo parseFrom(final byte[] bytes) throws DeserializationException { 749 if (bytes == null) return null; 750 return parseFrom(bytes, 0, bytes.length); 751 } 752 753 /** 754 * Parse a serialized representation of a {@link HRegionInfo}. 755 * @param bytes A pb RegionInfo serialized with a pb magic prefix. 756 * @param offset starting point in the byte array 757 * @param len length to read on the byte array 758 * @return A deserialized {@link HRegionInfo} n * @see #toByteArray() 759 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 760 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFrom(byte[], int, int)}. 761 */ 762 @Deprecated 763 public static HRegionInfo parseFrom(final byte[] bytes, int offset, int len) 764 throws DeserializationException { 765 if (ProtobufUtil.isPBMagicPrefix(bytes, offset, len)) { 766 int pblen = ProtobufUtil.lengthOfPBMagic(); 767 try { 768 HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder(); 769 ProtobufUtil.mergeFrom(builder, bytes, pblen + offset, len - pblen); 770 HBaseProtos.RegionInfo ri = builder.build(); 771 return convert(ri); 772 } catch (IOException e) { 773 throw new DeserializationException(e); 774 } 775 } else { 776 throw new DeserializationException("PB encoded HRegionInfo expected"); 777 } 778 } 779 780 /** 781 * Use this instead of {@link #toByteArray()} when writing to a stream and you want to use the pb 782 * mergeDelimitedFrom (w/o the delimiter, pb reads to EOF which may not be what you want). 783 * @return This instance serialized as a delimited protobuf w/ a magic pb prefix. n * @see 784 * #toByteArray() 785 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 786 * {@link RegionInfo#toDelimitedByteArray(RegionInfo)}. 787 */ 788 @Deprecated 789 public byte[] toDelimitedByteArray() throws IOException { 790 return RegionInfo.toDelimitedByteArray(this); 791 } 792 793 /** 794 * Get the descriptive name as {@link RegionState} does it but with hidden startkey optionally nn 795 * * @return descriptive string 796 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 797 * RegionInfoDisplay#getDescriptiveNameFromRegionStateForDisplay(RegionState, 798 * Configuration) over in hbase-server module. 799 */ 800 @Deprecated 801 @InterfaceAudience.Private 802 public static String getDescriptiveNameFromRegionStateForDisplay(RegionState state, 803 Configuration conf) { 804 return RegionInfoDisplay.getDescriptiveNameFromRegionStateForDisplay(state, conf); 805 } 806 807 /** 808 * Get the end key for display. Optionally hide the real end key. nn * @return the endkey 809 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 810 * RegionInfoDisplay#getEndKeyForDisplay(RegionInfo, Configuration) over in 811 * hbase-server module. 812 */ 813 @Deprecated 814 @InterfaceAudience.Private 815 public static byte[] getEndKeyForDisplay(HRegionInfo hri, Configuration conf) { 816 return RegionInfoDisplay.getEndKeyForDisplay(hri, conf); 817 } 818 819 /** 820 * Get the start key for display. Optionally hide the real start key. nn * @return the startkey 821 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 822 * RegionInfoDisplay#getStartKeyForDisplay(RegionInfo, Configuration) over in 823 * hbase-server module. 824 */ 825 @Deprecated 826 @InterfaceAudience.Private 827 public static byte[] getStartKeyForDisplay(HRegionInfo hri, Configuration conf) { 828 return RegionInfoDisplay.getStartKeyForDisplay(hri, conf); 829 } 830 831 /** 832 * Get the region name for display. Optionally hide the start key. nn * @return region name as 833 * String 834 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 835 * RegionInfoDisplay#getRegionNameAsStringForDisplay(RegionInfo, Configuration) over 836 * in hbase-server module. 837 */ 838 @Deprecated 839 @InterfaceAudience.Private 840 public static String getRegionNameAsStringForDisplay(HRegionInfo hri, Configuration conf) { 841 return RegionInfoDisplay.getRegionNameAsStringForDisplay(hri, conf); 842 } 843 844 /** 845 * Get the region name for display. Optionally hide the start key. nn * @return region name bytes 846 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 847 * RegionInfoDisplay#getRegionNameForDisplay(RegionInfo, Configuration) over in 848 * hbase-server module. 849 */ 850 @Deprecated 851 @InterfaceAudience.Private 852 public static byte[] getRegionNameForDisplay(HRegionInfo hri, Configuration conf) { 853 return RegionInfoDisplay.getRegionNameForDisplay(hri, conf); 854 } 855 856 /** 857 * Parses an HRegionInfo instance from the passed in stream. Presumes the HRegionInfo was 858 * serialized to the stream with {@link #toDelimitedByteArray()} n * @return An instance of 859 * HRegionInfo. n * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 860 * {@link RegionInfo#parseFrom(DataInputStream)}. 861 */ 862 @Deprecated 863 @InterfaceAudience.Private 864 public static HRegionInfo parseFrom(final DataInputStream in) throws IOException { 865 // I need to be able to move back in the stream if this is not a pb serialization so I can 866 // do the Writable decoding instead. 867 int pblen = ProtobufUtil.lengthOfPBMagic(); 868 byte[] pbuf = new byte[pblen]; 869 if (in.markSupported()) { // read it with mark() 870 in.mark(pblen); 871 } 872 873 // assumption: if Writable serialization, it should be longer than pblen. 874 in.readFully(pbuf, 0, pblen); 875 if (ProtobufUtil.isPBMagicPrefix(pbuf)) { 876 return convert(HBaseProtos.RegionInfo.parseDelimitedFrom(in)); 877 } else { 878 throw new IOException("PB encoded HRegionInfo expected"); 879 } 880 } 881 882 /** 883 * Serializes given HRegionInfo's as a byte array. Use this instead of {@link #toByteArray()} when 884 * writing to a stream and you want to use the pb mergeDelimitedFrom (w/o the delimiter, pb reads 885 * to EOF which may not be what you want). {@link #parseDelimitedFrom(byte[], int, int)} can be 886 * used to read back the instances. 887 * @param infos HRegionInfo objects to serialize 888 * @return This instance serialized as a delimited protobuf w/ a magic pb prefix. n * @see 889 * #toByteArray() 890 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 891 * {@link RegionInfo#toDelimitedByteArray(RegionInfo...)}. 892 */ 893 @Deprecated 894 @InterfaceAudience.Private 895 public static byte[] toDelimitedByteArray(HRegionInfo... infos) throws IOException { 896 return RegionInfo.toDelimitedByteArray(infos); 897 } 898 899 /** 900 * Parses all the HRegionInfo instances from the passed in stream until EOF. Presumes the 901 * HRegionInfo's were serialized to the stream with {@link #toDelimitedByteArray()} 902 * @param bytes serialized bytes 903 * @param offset the start offset into the byte[] buffer 904 * @param length how far we should read into the byte[] buffer 905 * @return All the hregioninfos that are in the byte array. Keeps reading till we hit the end. 906 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 907 * {@link RegionInfo#parseDelimitedFrom(byte[], int, int)}. 908 */ 909 @Deprecated 910 public static List<HRegionInfo> parseDelimitedFrom(final byte[] bytes, final int offset, 911 final int length) throws IOException { 912 if (bytes == null) { 913 throw new IllegalArgumentException("Can't build an object with empty bytes array"); 914 } 915 DataInputBuffer in = new DataInputBuffer(); 916 List<HRegionInfo> hris = new ArrayList<>(); 917 try { 918 in.reset(bytes, offset, length); 919 while (in.available() > 0) { 920 HRegionInfo hri = parseFrom(in); 921 hris.add(hri); 922 } 923 } finally { 924 in.close(); 925 } 926 return hris; 927 } 928 929 /** 930 * Check whether two regions are adjacent nn * @return true if two regions are adjacent 931 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 932 * {@link org.apache.hadoop.hbase.client.RegionInfo#areAdjacent(RegionInfo, RegionInfo)}. 933 */ 934 @Deprecated 935 public static boolean areAdjacent(HRegionInfo regionA, HRegionInfo regionB) { 936 return RegionInfo.areAdjacent(regionA, regionB); 937 } 938}