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