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 * @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 String nameAsString = null; 165 private int replicaId = DEFAULT_REPLICA_ID; 166 167 // Current TableName 168 private TableName tableName = null; 169 170 // Duplicated over in RegionInfoDisplay 171 final static String DISPLAY_KEYS_KEY = RegionInfoDisplay.DISPLAY_KEYS_KEY; 172 public final static byte[] HIDDEN_END_KEY = RegionInfoDisplay.HIDDEN_END_KEY; 173 public final static byte[] HIDDEN_START_KEY = RegionInfoDisplay.HIDDEN_START_KEY; 174 175 /** HRegionInfo for first meta region */ 176 // TODO: How come Meta regions still do not have encoded region names? Fix. 177 public static final HRegionInfo FIRST_META_REGIONINFO = 178 new HRegionInfo(1L, TableName.META_TABLE_NAME); 179 180 private void setHashCode() { 181 int result = Arrays.hashCode(this.regionName); 182 result = (int) (result ^ this.regionId); 183 result ^= Arrays.hashCode(this.startKey); 184 result ^= Arrays.hashCode(this.endKey); 185 result ^= Boolean.valueOf(this.offLine).hashCode(); 186 result ^= Arrays.hashCode(this.tableName.getName()); 187 result ^= this.replicaId; 188 this.hashCode = result; 189 } 190 191 /** 192 * Private constructor used constructing HRegionInfo for the first meta regions 193 */ 194 private HRegionInfo(long regionId, TableName tableName) { 195 this(regionId, tableName, DEFAULT_REPLICA_ID); 196 } 197 198 public HRegionInfo(long regionId, TableName tableName, int replicaId) { 199 super(); 200 this.regionId = regionId; 201 this.tableName = tableName; 202 this.replicaId = replicaId; 203 // Note: First Meta region replicas names are in old format 204 this.regionName = createRegionName(tableName, null, regionId, replicaId, false); 205 setHashCode(); 206 } 207 208 public HRegionInfo(final TableName tableName) { 209 this(tableName, null, null); 210 } 211 212 /** 213 * Construct HRegionInfo with explicit parameters 214 * @param tableName the table name 215 * @param startKey first key in region 216 * @param endKey end of key range 217 */ 218 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey) 219 throws IllegalArgumentException { 220 this(tableName, startKey, endKey, false); 221 } 222 223 /** 224 * Construct HRegionInfo with explicit parameters 225 * @param tableName the table name 226 * @param startKey first key in region 227 * @param endKey end of key range 228 * @param split true if this region has split and we have daughter regions regions that may or 229 * may not hold references to this region. 230 */ 231 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey, 232 final boolean split) throws IllegalArgumentException { 233 this(tableName, startKey, endKey, split, EnvironmentEdgeManager.currentTime()); 234 } 235 236 /** 237 * Construct HRegionInfo with explicit parameters 238 * @param tableName the table name 239 * @param startKey first key in region 240 * @param endKey end of key range 241 * @param split true if this region has split and we have daughter regions regions that may or 242 * may not hold references to this region. 243 * @param regionId Region id to use. 244 */ 245 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey, 246 final boolean split, final long regionId) throws IllegalArgumentException { 247 this(tableName, startKey, endKey, split, regionId, DEFAULT_REPLICA_ID); 248 } 249 250 /** 251 * Construct HRegionInfo with explicit parameters 252 * @param tableName the table name 253 * @param startKey first key in region 254 * @param endKey end of key range 255 * @param split true if this region has split and we have daughter regions regions that may or 256 * may not hold references to this region. 257 * @param regionId Region id to use. 258 * @param replicaId the replicaId to use 259 */ 260 public HRegionInfo(final TableName tableName, final byte[] startKey, final byte[] endKey, 261 final boolean split, final long regionId, final int replicaId) throws IllegalArgumentException { 262 super(); 263 if (tableName == null) { 264 throw new IllegalArgumentException("TableName cannot be null"); 265 } 266 this.tableName = tableName; 267 this.offLine = false; 268 this.regionId = regionId; 269 this.replicaId = replicaId; 270 if (this.replicaId > MAX_REPLICA_ID) { 271 throw new IllegalArgumentException("ReplicaId cannot be greater than" + MAX_REPLICA_ID); 272 } 273 274 this.regionName = createRegionName(this.tableName, startKey, regionId, replicaId, true); 275 276 this.split = split; 277 this.endKey = endKey == null ? HConstants.EMPTY_END_ROW : endKey.clone(); 278 this.startKey = startKey == null ? HConstants.EMPTY_START_ROW : startKey.clone(); 279 this.tableName = tableName; 280 setHashCode(); 281 } 282 283 /** 284 * Construct a copy of another HRegionInfo 285 */ 286 public HRegionInfo(RegionInfo other) { 287 super(); 288 this.endKey = other.getEndKey(); 289 this.offLine = other.isOffline(); 290 this.regionId = other.getRegionId(); 291 this.regionName = other.getRegionName(); 292 this.split = other.isSplit(); 293 this.startKey = other.getStartKey(); 294 this.hashCode = other.hashCode(); 295 this.encodedName = other.getEncodedName(); 296 this.tableName = other.getTable(); 297 this.replicaId = other.getReplicaId(); 298 } 299 300 public HRegionInfo(HRegionInfo other, int replicaId) { 301 this(other); 302 this.replicaId = replicaId; 303 this.setHashCode(); 304 } 305 306 /** 307 * Make a region name of passed parameters. 308 * @param tableName the table name 309 * @param startKey Can be null 310 * @param regionId Region id (Usually timestamp from when region was created). 311 * @param newFormat should we create the region name in the new format (such that it contains its 312 * encoded name?). 313 * @return Region name made of passed tableName, startKey and id 314 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 315 * {@link RegionInfo#createRegionName(TableName, byte[], long, boolean)}. 316 */ 317 @Deprecated 318 @InterfaceAudience.Private 319 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 320 final long regionId, boolean newFormat) { 321 return RegionInfo.createRegionName(tableName, startKey, Long.toString(regionId), newFormat); 322 } 323 324 /** 325 * Make a region name of passed parameters. 326 * @param tableName the table name 327 * @param startKey Can be null 328 * @param id Region id (Usually timestamp from when region was created). 329 * @param newFormat should we create the region name in the new format (such that it contains its 330 * encoded name?). 331 * @return Region name made of passed tableName, startKey and id 332 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 333 * {@link RegionInfo#createRegionName(TableName, byte[], String, boolean)}. 334 */ 335 @Deprecated 336 @InterfaceAudience.Private 337 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 338 final String id, boolean newFormat) { 339 return RegionInfo.createRegionName(tableName, startKey, Bytes.toBytes(id), newFormat); 340 } 341 342 /** 343 * Make a region name of passed parameters. 344 * @param tableName the table name 345 * @param startKey Can be null 346 * @param regionId Region id (Usually timestamp from when region was created). 347 * @param newFormat should we create the region name in the new format (such that it contains its 348 * encoded name?). 349 * @return Region name made of passed tableName, startKey, id and replicaId 350 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 351 * {@link RegionInfo#createRegionName(TableName, byte[], long, int, boolean)}. 352 */ 353 @Deprecated 354 @InterfaceAudience.Private 355 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 356 final long regionId, int replicaId, boolean newFormat) { 357 return RegionInfo.createRegionName(tableName, startKey, Bytes.toBytes(Long.toString(regionId)), 358 replicaId, newFormat); 359 } 360 361 /** 362 * Make a region name of passed parameters. 363 * @param tableName the table name 364 * @param startKey Can be null 365 * @param id Region id (Usually timestamp from when region was created). 366 * @param newFormat should we create the region name in the new format (such that it contains its 367 * encoded name?). 368 * @return Region name made of passed tableName, startKey and id 369 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 370 * {@link RegionInfo#createRegionName(TableName, byte[], byte[], boolean)}. 371 */ 372 @Deprecated 373 @InterfaceAudience.Private 374 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 375 final byte[] id, boolean newFormat) { 376 return RegionInfo.createRegionName(tableName, startKey, id, DEFAULT_REPLICA_ID, newFormat); 377 } 378 379 /** 380 * Make a region name of passed parameters. 381 * @param tableName the table name 382 * @param startKey Can be null 383 * @param id Region id (Usually timestamp from when region was created) 384 * @param newFormat should we create the region name in the new format 385 * @return Region name made of passed tableName, startKey, id and replicaId 386 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 387 * {@link RegionInfo#createRegionName(TableName, byte[], byte[], int, boolean)}. 388 */ 389 @Deprecated 390 @InterfaceAudience.Private 391 public static byte[] createRegionName(final TableName tableName, final byte[] startKey, 392 final byte[] id, final int replicaId, boolean newFormat) { 393 return RegionInfo.createRegionName(tableName, startKey, id, replicaId, newFormat); 394 } 395 396 /** 397 * Gets the table name from the specified region name. 398 * @param regionName to extract the table name from 399 * @return Table name 400 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 401 * {@link org.apache.hadoop.hbase.client.RegionInfo#getTable(byte[])}. 402 */ 403 @Deprecated 404 public static TableName getTable(final byte[] regionName) { 405 return RegionInfo.getTable(regionName); 406 } 407 408 /** 409 * Gets the start key from the specified region name. 410 * @return Start key. 411 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 412 * {@link org.apache.hadoop.hbase.client.RegionInfo#getStartKey(byte[])}. 413 */ 414 @Deprecated 415 public static byte[] getStartKey(final byte[] regionName) throws IOException { 416 return RegionInfo.getStartKey(regionName); 417 } 418 419 /** 420 * Separate elements of a regionName. 421 * @return Array of byte[] containing tableName, startKey and id 422 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 423 * {@link RegionInfo#parseRegionName(byte[])}. 424 */ 425 @Deprecated 426 @InterfaceAudience.Private 427 public static byte[][] parseRegionName(final byte[] regionName) throws IOException { 428 return RegionInfo.parseRegionName(regionName); 429 } 430 431 /** 432 * @return if region name is encoded. 433 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 434 * {@link org.apache.hadoop.hbase.client.RegionInfo#isEncodedRegionName(byte[])}. 435 */ 436 @Deprecated 437 public static boolean isEncodedRegionName(byte[] regionName) throws IOException { 438 return RegionInfo.isEncodedRegionName(regionName); 439 } 440 441 /** Returns the regionId */ 442 @Override 443 public long getRegionId() { 444 return regionId; 445 } 446 447 /** 448 * @return the regionName as an array of bytes. 449 * @see #getRegionNameAsString() 450 */ 451 @Override 452 public byte[] getRegionName() { 453 return regionName; 454 } 455 456 /** Returns Region name as a String for use in logging, etc. */ 457 @Override 458 public String getRegionNameAsString() { 459 if (nameAsString == null) { 460 String name; 461 if (RegionInfo.hasEncodedName(this.regionName)) { 462 // new format region names already have their encoded name. 463 name = Bytes.toStringBinary(this.regionName); 464 } else { 465 // old format. regionNameStr doesn't have the region name. 466 name = Bytes.toStringBinary(this.regionName) + "." + this.getEncodedName(); 467 } 468 // may race with other threads setting this, but that's ok 469 nameAsString = name; 470 return name; 471 } else { 472 return nameAsString; 473 } 474 } 475 476 /** Returns the encoded region name */ 477 @Override 478 public synchronized String getEncodedName() { 479 if (this.encodedName == null) { 480 this.encodedName = RegionInfo.encodeRegionName(this.regionName); 481 } 482 return this.encodedName; 483 } 484 485 @Override 486 public synchronized byte[] getEncodedNameAsBytes() { 487 if (this.encodedNameAsBytes == null) { 488 this.encodedNameAsBytes = Bytes.toBytes(getEncodedName()); 489 } 490 return this.encodedNameAsBytes; 491 } 492 493 /** Returns the startKey */ 494 @Override 495 public byte[] getStartKey() { 496 return startKey; 497 } 498 499 /** Returns the endKey */ 500 @Override 501 public byte[] getEndKey() { 502 return endKey; 503 } 504 505 /** 506 * Get current table name of the region 507 */ 508 @Override 509 public TableName getTable() { 510 // This method name should be getTableName but there was already a method getTableName 511 // that returned a byte array. It is unfortunate given everywhere else, getTableName returns 512 // a TableName instance. 513 if (tableName == null || tableName.getName().length == 0) { 514 tableName = getTable(getRegionName()); 515 } 516 return this.tableName; 517 } 518 519 /** 520 * Returns true if the given inclusive range of rows is fully contained by this region. For 521 * example, if the region is foo,a,g and this is passed ["b","c"] or ["a","c"] it will return 522 * true, but if this is passed ["b","z"] it will return false. 523 * @throws IllegalArgumentException if the range passed is invalid (ie. end < start) 524 */ 525 @Override 526 public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) { 527 if (Bytes.compareTo(rangeStartKey, rangeEndKey) > 0) { 528 throw new IllegalArgumentException("Invalid range: " + Bytes.toStringBinary(rangeStartKey) 529 + " > " + Bytes.toStringBinary(rangeEndKey)); 530 } 531 532 boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) >= 0; 533 boolean lastKeyInRange = 534 Bytes.compareTo(rangeEndKey, endKey) < 0 || Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY); 535 return firstKeyInRange && lastKeyInRange; 536 } 537 538 /** Returns true if the given row falls in this region. */ 539 @Override 540 public boolean containsRow(byte[] row) { 541 return Bytes.compareTo(row, startKey) >= 0 542 && (Bytes.compareTo(row, endKey) < 0 || Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY)); 543 } 544 545 /** Returns true if this region is from hbase:meta */ 546 public boolean isMetaTable() { 547 return isMetaRegion(); 548 } 549 550 /** Returns true if this region is a meta region */ 551 @Override 552 public boolean isMetaRegion() { 553 return tableName.equals(HRegionInfo.FIRST_META_REGIONINFO.getTable()); 554 } 555 556 /** Returns true if this region is from a system table */ 557 public boolean isSystemTable() { 558 return tableName.isSystemTable(); 559 } 560 561 /** Returns true if has been split and has daughters. */ 562 @Override 563 public boolean isSplit() { 564 return this.split; 565 } 566 567 /** 568 * Set or clear the split status flag. 569 * @param split set split status 570 */ 571 public void setSplit(boolean split) { 572 this.split = split; 573 } 574 575 /** Returns true if this region is offline. */ 576 @Override 577 public boolean isOffline() { 578 return this.offLine; 579 } 580 581 /** 582 * The parent of a region split is offline while split daughters hold references to the parent. 583 * Offlined regions are closed. 584 * @param offLine Set online/offline status. 585 */ 586 public void setOffline(boolean offLine) { 587 this.offLine = offLine; 588 } 589 590 /** Returns true if this is a split parent region. */ 591 @Override 592 public boolean isSplitParent() { 593 if (!isSplit()) return false; 594 if (!isOffline()) { 595 LOG.warn("Region is split but NOT offline: " + getRegionNameAsString()); 596 } 597 return true; 598 } 599 600 /** 601 * Returns the region replica id 602 * @return returns region replica id 603 */ 604 @Override 605 public int getReplicaId() { 606 return replicaId; 607 } 608 609 /** 610 * @see java.lang.Object#toString() 611 */ 612 @Override 613 public String toString() { 614 return "{ENCODED => " + getEncodedName() + ", " + HConstants.NAME + " => '" 615 + Bytes.toStringBinary(this.regionName) + "', STARTKEY => '" 616 + Bytes.toStringBinary(this.startKey) + "', ENDKEY => '" + Bytes.toStringBinary(this.endKey) 617 + "'" + (isOffline() ? ", OFFLINE => true" : "") + (isSplit() ? ", SPLIT => true" : "") 618 + ((replicaId > 0) ? ", REPLICA_ID => " + replicaId : "") + "}"; 619 } 620 621 /** 622 * @see java.lang.Object#equals(java.lang.Object) 623 */ 624 @Override 625 public boolean equals(Object o) { 626 if (this == o) { 627 return true; 628 } 629 if (o == null) { 630 return false; 631 } 632 if (!(o instanceof HRegionInfo)) { 633 return false; 634 } 635 return this.compareTo((HRegionInfo) o) == 0; 636 } 637 638 /** 639 * @see java.lang.Object#hashCode() 640 */ 641 @Override 642 public int hashCode() { 643 return this.hashCode; 644 } 645 646 /** 647 * @return Comparator to use comparing {@link KeyValue}s. 648 * @deprecated Use Region#getCellComparator(). deprecated for hbase 2.0, remove for hbase 3.0 649 */ 650 @Deprecated 651 public KVComparator getComparator() { 652 return isMetaRegion() ? KeyValue.META_COMPARATOR : KeyValue.COMPARATOR; 653 } 654 655 /** 656 * Convert a HRegionInfo to the protobuf RegionInfo 657 * @return the converted RegionInfo 658 */ 659 HBaseProtos.RegionInfo convert() { 660 return convert(this); 661 } 662 663 /** 664 * Convert a HRegionInfo to a RegionInfo 665 * @param info the HRegionInfo to convert 666 * @return the converted RegionInfo 667 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 668 * toRegionInfo(org.apache.hadoop.hbase.client.RegionInfo) in 669 * org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil. 670 */ 671 @Deprecated 672 @InterfaceAudience.Private 673 public static HBaseProtos.RegionInfo convert(final HRegionInfo info) { 674 return ProtobufUtil.toRegionInfo(info); 675 } 676 677 /** 678 * Convert a RegionInfo to a HRegionInfo 679 * @param proto the RegionInfo to convert 680 * @return the converted HRegionInfo 681 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 682 * toRegionInfo(HBaseProtos.RegionInfo) in 683 * org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil. 684 */ 685 @Deprecated 686 @InterfaceAudience.Private 687 public static HRegionInfo convert(final HBaseProtos.RegionInfo proto) { 688 RegionInfo ri = ProtobufUtil.toRegionInfo(proto); 689 // This is hack of what is in RegionReplicaUtil but it is doing translation of 690 // RegionInfo into HRegionInfo which is what is wanted here. 691 HRegionInfo hri; 692 if (ri.isMetaRegion()) { 693 hri = ri.getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID 694 ? HRegionInfo.FIRST_META_REGIONINFO 695 : new HRegionInfo(ri.getRegionId(), ri.getTable(), ri.getReplicaId()); 696 } else { 697 hri = new HRegionInfo(ri.getTable(), ri.getStartKey(), ri.getEndKey(), ri.isSplit(), 698 ri.getRegionId(), ri.getReplicaId()); 699 if (proto.hasOffline()) { 700 hri.setOffline(proto.getOffline()); 701 } 702 } 703 return hri; 704 } 705 706 /** 707 * Serialize a {@link HRegionInfo} into a byte array. 708 * @return This instance serialized as protobuf w/ a magic pb prefix. 709 * @see #parseFrom(byte[]) 710 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 711 * {@link org.apache.hadoop.hbase.client.RegionInfo#toByteArray(RegionInfo)}. 712 */ 713 @Deprecated 714 public byte[] toByteArray() { 715 return RegionInfo.toByteArray(this); 716 } 717 718 /** 719 * Parse a serialized representation of a {@link HRegionInfo}. 720 * @return A deserialized {@link HRegionInfo} or null if we failed deserialize or passed bytes 721 * null 722 * @see #toByteArray() 723 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 724 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFromOrNull(byte[])}. 725 */ 726 @Deprecated 727 public static HRegionInfo parseFromOrNull(final byte[] bytes) { 728 if (bytes == null) return null; 729 return parseFromOrNull(bytes, 0, bytes.length); 730 } 731 732 /** 733 * Parse a serialized representation of a {@link HRegionInfo}. 734 * @return A deserialized {@link HRegionInfo} or null if we failed deserialize or passed bytes 735 * null 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#parseFromOrNull(byte[], int, int)}. 739 */ 740 @Deprecated 741 public static HRegionInfo parseFromOrNull(final byte[] bytes, int offset, int len) { 742 if (bytes == null || len <= 0) return null; 743 try { 744 return parseFrom(bytes, offset, len); 745 } catch (DeserializationException e) { 746 return null; 747 } 748 } 749 750 /** 751 * Parse a serialized representation of a {@link HRegionInfo}. 752 * @param bytes A pb RegionInfo serialized with a pb magic prefix. 753 * @return A deserialized {@link HRegionInfo} 754 * @see #toByteArray() 755 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 756 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFrom(byte[])}. 757 */ 758 public static HRegionInfo parseFrom(final byte[] bytes) throws DeserializationException { 759 if (bytes == null) return null; 760 return parseFrom(bytes, 0, bytes.length); 761 } 762 763 /** 764 * Parse a serialized representation of a {@link HRegionInfo}. 765 * @param bytes A pb RegionInfo serialized with a pb magic prefix. 766 * @param offset starting point in the byte array 767 * @param len length to read on the byte array 768 * @return A deserialized {@link HRegionInfo} 769 * @see #toByteArray() 770 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 771 * {@link org.apache.hadoop.hbase.client.RegionInfo#parseFrom(byte[], int, int)}. 772 */ 773 @Deprecated 774 public static HRegionInfo parseFrom(final byte[] bytes, int offset, int len) 775 throws DeserializationException { 776 if (ProtobufUtil.isPBMagicPrefix(bytes, offset, len)) { 777 int pblen = ProtobufUtil.lengthOfPBMagic(); 778 try { 779 HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder(); 780 ProtobufUtil.mergeFrom(builder, bytes, pblen + offset, len - pblen); 781 HBaseProtos.RegionInfo ri = builder.build(); 782 return convert(ri); 783 } catch (IOException e) { 784 throw new DeserializationException(e); 785 } 786 } else { 787 throw new DeserializationException("PB encoded HRegionInfo expected"); 788 } 789 } 790 791 /** 792 * Use this instead of {@link #toByteArray()} when writing to a stream and you want to use the pb 793 * mergeDelimitedFrom (w/o the delimiter, pb reads to EOF which may not be what you want). 794 * @return This instance serialized as a delimited protobuf w/ a magic pb prefix. 795 * @see #toByteArray() 796 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 797 * {@link RegionInfo#toDelimitedByteArray(RegionInfo)}. 798 */ 799 @Deprecated 800 public byte[] toDelimitedByteArray() throws IOException { 801 return RegionInfo.toDelimitedByteArray(this); 802 } 803 804 /** 805 * Get the descriptive name as {@link RegionState} does it but with hidden startkey optionally 806 * @return descriptive string 807 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 808 * RegionInfoDisplay#getDescriptiveNameFromRegionStateForDisplay(RegionState, 809 * Configuration) over in hbase-server module. 810 */ 811 @Deprecated 812 @InterfaceAudience.Private 813 public static String getDescriptiveNameFromRegionStateForDisplay(RegionState state, 814 Configuration conf) { 815 return RegionInfoDisplay.getDescriptiveNameFromRegionStateForDisplay(state, conf); 816 } 817 818 /** 819 * Get the end key for display. Optionally hide the real end key. 820 * @return the endkey 821 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 822 * RegionInfoDisplay#getEndKeyForDisplay(RegionInfo, Configuration) over in 823 * hbase-server module. 824 */ 825 @Deprecated 826 @InterfaceAudience.Private 827 public static byte[] getEndKeyForDisplay(HRegionInfo hri, Configuration conf) { 828 return RegionInfoDisplay.getEndKeyForDisplay(hri, conf); 829 } 830 831 /** 832 * Get the start key for display. Optionally hide the real start key. 833 * @return the startkey 834 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 835 * RegionInfoDisplay#getStartKeyForDisplay(RegionInfo, Configuration) over in 836 * hbase-server module. 837 */ 838 @Deprecated 839 @InterfaceAudience.Private 840 public static byte[] getStartKeyForDisplay(HRegionInfo hri, Configuration conf) { 841 return RegionInfoDisplay.getStartKeyForDisplay(hri, conf); 842 } 843 844 /** 845 * Get the region name for display. Optionally hide the start key. 846 * @return region name as String 847 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 848 * RegionInfoDisplay#getRegionNameAsStringForDisplay(RegionInfo, Configuration) over 849 * in hbase-server module. 850 */ 851 @Deprecated 852 @InterfaceAudience.Private 853 public static String getRegionNameAsStringForDisplay(HRegionInfo hri, Configuration conf) { 854 return RegionInfoDisplay.getRegionNameAsStringForDisplay(hri, conf); 855 } 856 857 /** 858 * Get the region name for display. Optionally hide the start key. 859 * @return region name bytes 860 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 861 * RegionInfoDisplay#getRegionNameForDisplay(RegionInfo, Configuration) over in 862 * hbase-server module. 863 */ 864 @Deprecated 865 @InterfaceAudience.Private 866 public static byte[] getRegionNameForDisplay(HRegionInfo hri, Configuration conf) { 867 return RegionInfoDisplay.getRegionNameForDisplay(hri, conf); 868 } 869 870 /** 871 * Parses an HRegionInfo instance from the passed in stream. Presumes the HRegionInfo was 872 * serialized to the stream with {@link #toDelimitedByteArray()} 873 * @return An instance of HRegionInfo. 874 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 875 * {@link RegionInfo#parseFrom(DataInputStream)}. 876 */ 877 @Deprecated 878 @InterfaceAudience.Private 879 public static HRegionInfo parseFrom(final DataInputStream in) throws IOException { 880 // I need to be able to move back in the stream if this is not a pb serialization so I can 881 // do the Writable decoding instead. 882 int pblen = ProtobufUtil.lengthOfPBMagic(); 883 byte[] pbuf = new byte[pblen]; 884 if (in.markSupported()) { // read it with mark() 885 in.mark(pblen); 886 } 887 888 // assumption: if Writable serialization, it should be longer than pblen. 889 in.readFully(pbuf, 0, pblen); 890 if (ProtobufUtil.isPBMagicPrefix(pbuf)) { 891 return convert(HBaseProtos.RegionInfo.parseDelimitedFrom(in)); 892 } else { 893 throw new IOException("PB encoded HRegionInfo expected"); 894 } 895 } 896 897 /** 898 * Serializes given HRegionInfo's as a byte array. Use this instead of {@link #toByteArray()} when 899 * writing to a stream and you want to use the pb mergeDelimitedFrom (w/o the delimiter, pb reads 900 * to EOF which may not be what you want). {@link #parseDelimitedFrom(byte[], int, int)} can be 901 * used to read back the instances. 902 * @param infos HRegionInfo objects to serialize 903 * @return This instance serialized as a delimited protobuf w/ a magic pb prefix. 904 * @see #toByteArray() 905 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 906 * {@link RegionInfo#toDelimitedByteArray(RegionInfo...)}. 907 */ 908 @Deprecated 909 @InterfaceAudience.Private 910 public static byte[] toDelimitedByteArray(HRegionInfo... infos) throws IOException { 911 return RegionInfo.toDelimitedByteArray(infos); 912 } 913 914 /** 915 * Parses all the HRegionInfo instances from the passed in stream until EOF. Presumes the 916 * HRegionInfo's were serialized to the stream with {@link #toDelimitedByteArray()} 917 * @param bytes serialized bytes 918 * @param offset the start offset into the byte[] buffer 919 * @param length how far we should read into the byte[] buffer 920 * @return All the hregioninfos that are in the byte array. Keeps reading till we hit the end. 921 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 922 * {@link RegionInfo#parseDelimitedFrom(byte[], int, int)}. 923 */ 924 @Deprecated 925 public static List<HRegionInfo> parseDelimitedFrom(final byte[] bytes, final int offset, 926 final int length) throws IOException { 927 if (bytes == null) { 928 throw new IllegalArgumentException("Can't build an object with empty bytes array"); 929 } 930 DataInputBuffer in = new DataInputBuffer(); 931 List<HRegionInfo> hris = new ArrayList<>(); 932 try { 933 in.reset(bytes, offset, length); 934 while (in.available() > 0) { 935 HRegionInfo hri = parseFrom(in); 936 hris.add(hri); 937 } 938 } finally { 939 in.close(); 940 } 941 return hris; 942 } 943 944 /** 945 * Check whether two regions are adjacent 946 * @return true if two regions are adjacent 947 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0 Use 948 * {@link org.apache.hadoop.hbase.client.RegionInfo#areAdjacent(RegionInfo, RegionInfo)}. 949 */ 950 @Deprecated 951 public static boolean areAdjacent(HRegionInfo regionA, HRegionInfo regionB) { 952 return RegionInfo.areAdjacent(regionA, regionB); 953 } 954}