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 */ 018 019package org.apache.hadoop.hbase; 020 021import static org.apache.hadoop.hbase.KeyValue.COLUMN_FAMILY_DELIMITER; 022import static org.apache.hadoop.hbase.KeyValue.COLUMN_FAMILY_DELIM_ARRAY; 023import static org.apache.hadoop.hbase.KeyValue.getDelimiter; 024import static org.apache.hadoop.hbase.Tag.TAG_LENGTH_SIZE; 025 026import java.io.DataOutput; 027import java.io.DataOutputStream; 028import java.io.IOException; 029import java.nio.ByteBuffer; 030import java.util.ArrayList; 031import java.util.Arrays; 032import java.util.Iterator; 033import java.util.List; 034import java.util.Map.Entry; 035import java.util.NavigableMap; 036import java.util.Optional; 037import java.util.function.Function; 038import org.apache.hadoop.hbase.KeyValue.Type; 039import org.apache.hadoop.hbase.io.HeapSize; 040import org.apache.hadoop.hbase.util.ByteBufferUtils; 041import org.apache.hadoop.hbase.util.ByteRange; 042import org.apache.hadoop.hbase.util.Bytes; 043import org.apache.yetus.audience.InterfaceAudience; 044import org.apache.yetus.audience.InterfaceAudience.Private; 045 046/** 047 * Utility methods helpful for slinging {@link Cell} instances. Some methods below are for internal 048 * use only and are marked InterfaceAudience.Private at the method level. Note that all such methods 049 * have been marked deprecated in HBase-2.0 which will be subsequently removed in HBase-3.0 050 */ 051@InterfaceAudience.Public 052public final class CellUtil { 053 054 /** 055 * Private constructor to keep this class from being instantiated. 056 */ 057 private CellUtil() { 058 } 059 060 /******************* ByteRange *******************************/ 061 062 /** 063 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 064 */ 065 @Deprecated 066 public static ByteRange fillRowRange(Cell cell, ByteRange range) { 067 return range.set(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()); 068 } 069 070 /** 071 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 072 */ 073 @Deprecated 074 public static ByteRange fillFamilyRange(Cell cell, ByteRange range) { 075 return range.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()); 076 } 077 078 /** 079 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 080 */ 081 @Deprecated 082 public static ByteRange fillQualifierRange(Cell cell, ByteRange range) { 083 return range.set(cell.getQualifierArray(), cell.getQualifierOffset(), 084 cell.getQualifierLength()); 085 } 086 087 /** 088 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 089 */ 090 @Deprecated 091 public static ByteRange fillValueRange(Cell cell, ByteRange range) { 092 return range.set(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); 093 } 094 095 /** 096 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 097 */ 098 @Deprecated 099 public static ByteRange fillTagRange(Cell cell, ByteRange range) { 100 return range.set(cell.getTagsArray(), cell.getTagsOffset(), cell.getTagsLength()); 101 } 102 103 /***************** get individual arrays for tests ************/ 104 105 public static byte[] cloneRow(Cell cell) { 106 byte[] output = new byte[cell.getRowLength()]; 107 copyRowTo(cell, output, 0); 108 return output; 109 } 110 111 public static byte[] cloneFamily(Cell cell) { 112 byte[] output = new byte[cell.getFamilyLength()]; 113 copyFamilyTo(cell, output, 0); 114 return output; 115 } 116 117 public static byte[] cloneQualifier(Cell cell) { 118 byte[] output = new byte[cell.getQualifierLength()]; 119 copyQualifierTo(cell, output, 0); 120 return output; 121 } 122 123 public static byte[] cloneValue(Cell cell) { 124 byte[] output = new byte[cell.getValueLength()]; 125 copyValueTo(cell, output, 0); 126 return output; 127 } 128 129 /** 130 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 131 * Use {@link RawCell#cloneTags()} 132 */ 133 @Deprecated 134 public static byte[] cloneTags(Cell cell) { 135 byte[] output = new byte[cell.getTagsLength()]; 136 PrivateCellUtil.copyTagsTo(cell, output, 0); 137 return output; 138 } 139 140 /** 141 * Returns tag value in a new byte array. If server-side, use {@link Tag#getValueArray()} with 142 * appropriate {@link Tag#getValueOffset()} and {@link Tag#getValueLength()} instead to save on 143 * allocations. 144 * @param cell 145 * @return tag value in a new byte array. 146 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 147 */ 148 @Deprecated 149 public static byte[] getTagArray(Cell cell) { 150 byte[] output = new byte[cell.getTagsLength()]; 151 PrivateCellUtil.copyTagsTo(cell, output, 0); 152 return output; 153 } 154 155 /** 156 * Makes a column in family:qualifier form from separate byte arrays. 157 * <p> 158 * Not recommended for usage as this is old-style API. 159 * @param family 160 * @param qualifier 161 * @return family:qualifier 162 */ 163 public static byte[] makeColumn(byte[] family, byte[] qualifier) { 164 return Bytes.add(family, COLUMN_FAMILY_DELIM_ARRAY, qualifier); 165 } 166 167 /** 168 * Splits a column in {@code family:qualifier} form into separate byte arrays. An empty qualifier 169 * (ie, {@code fam:}) is parsed as <code>{ fam, EMPTY_BYTE_ARRAY }</code> while no delimiter (ie, 170 * {@code fam}) is parsed as an array of one element, <code>{ fam }</code>. 171 * <p> 172 * Don't forget, HBase DOES support empty qualifiers. (see HBASE-9549) 173 * </p> 174 * <p> 175 * Not recommend to be used as this is old-style API. 176 * </p> 177 * @param c The column. 178 * @return The parsed column. 179 */ 180 public static byte[][] parseColumn(byte[] c) { 181 final int index = getDelimiter(c, 0, c.length, COLUMN_FAMILY_DELIMITER); 182 if (index == -1) { 183 // If no delimiter, return array of size 1 184 return new byte[][] { c }; 185 } else if (index == c.length - 1) { 186 // family with empty qualifier, return array size 2 187 byte[] family = new byte[c.length - 1]; 188 System.arraycopy(c, 0, family, 0, family.length); 189 return new byte[][] { family, HConstants.EMPTY_BYTE_ARRAY }; 190 } 191 // Family and column, return array size 2 192 final byte[][] result = new byte[2][]; 193 result[0] = new byte[index]; 194 System.arraycopy(c, 0, result[0], 0, index); 195 final int len = c.length - (index + 1); 196 result[1] = new byte[len]; 197 System.arraycopy(c, index + 1 /* Skip delimiter */, result[1], 0, len); 198 return result; 199 } 200 201 /******************** copyTo **********************************/ 202 203 /** 204 * Copies the row to the given byte[] 205 * @param cell the cell whose row has to be copied 206 * @param destination the destination byte[] to which the row has to be copied 207 * @param destinationOffset the offset in the destination byte[] 208 * @return the offset of the byte[] after the copy has happened 209 */ 210 public static int copyRowTo(Cell cell, byte[] destination, int destinationOffset) { 211 short rowLen = cell.getRowLength(); 212 if (cell instanceof ByteBufferExtendedCell) { 213 ByteBufferUtils.copyFromBufferToArray(destination, 214 ((ByteBufferExtendedCell) cell).getRowByteBuffer(), 215 ((ByteBufferExtendedCell) cell).getRowPosition(), destinationOffset, rowLen); 216 } else { 217 System.arraycopy(cell.getRowArray(), cell.getRowOffset(), destination, destinationOffset, 218 rowLen); 219 } 220 return destinationOffset + rowLen; 221 } 222 223 /** 224 * Copies the row to the given bytebuffer 225 * @param cell cell the cell whose row has to be copied 226 * @param destination the destination bytebuffer to which the row has to be copied 227 * @param destinationOffset the offset in the destination byte[] 228 * @return the offset of the bytebuffer after the copy has happened 229 */ 230 public static int copyRowTo(Cell cell, ByteBuffer destination, int destinationOffset) { 231 short rowLen = cell.getRowLength(); 232 if (cell instanceof ByteBufferExtendedCell) { 233 ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferExtendedCell) cell).getRowByteBuffer(), 234 destination, ((ByteBufferExtendedCell) cell).getRowPosition(), destinationOffset, rowLen); 235 } else { 236 ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getRowArray(), 237 cell.getRowOffset(), rowLen); 238 } 239 return destinationOffset + rowLen; 240 } 241 242 /** 243 * Copies the row to a new byte[] 244 * @param cell the cell from which row has to copied 245 * @return the byte[] containing the row 246 */ 247 public static byte[] copyRow(Cell cell) { 248 if (cell instanceof ByteBufferExtendedCell) { 249 return ByteBufferUtils.copyOfRange(((ByteBufferExtendedCell) cell).getRowByteBuffer(), 250 ((ByteBufferExtendedCell) cell).getRowPosition(), 251 ((ByteBufferExtendedCell) cell).getRowPosition() + cell.getRowLength()); 252 } else { 253 return Arrays.copyOfRange(cell.getRowArray(), cell.getRowOffset(), 254 cell.getRowOffset() + cell.getRowLength()); 255 } 256 } 257 258 /** 259 * Copies the family to the given byte[] 260 * @param cell the cell whose family has to be copied 261 * @param destination the destination byte[] to which the family has to be copied 262 * @param destinationOffset the offset in the destination byte[] 263 * @return the offset of the byte[] after the copy has happened 264 */ 265 public static int copyFamilyTo(Cell cell, byte[] destination, int destinationOffset) { 266 byte fLen = cell.getFamilyLength(); 267 if (cell instanceof ByteBufferExtendedCell) { 268 ByteBufferUtils.copyFromBufferToArray(destination, 269 ((ByteBufferExtendedCell) cell).getFamilyByteBuffer(), 270 ((ByteBufferExtendedCell) cell).getFamilyPosition(), destinationOffset, fLen); 271 } else { 272 System.arraycopy(cell.getFamilyArray(), cell.getFamilyOffset(), destination, 273 destinationOffset, fLen); 274 } 275 return destinationOffset + fLen; 276 } 277 278 /** 279 * Copies the family to the given bytebuffer 280 * @param cell the cell whose family has to be copied 281 * @param destination the destination bytebuffer to which the family has to be copied 282 * @param destinationOffset the offset in the destination bytebuffer 283 * @return the offset of the bytebuffer after the copy has happened 284 */ 285 public static int copyFamilyTo(Cell cell, ByteBuffer destination, int destinationOffset) { 286 byte fLen = cell.getFamilyLength(); 287 if (cell instanceof ByteBufferExtendedCell) { 288 ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferExtendedCell) cell).getFamilyByteBuffer(), 289 destination, ((ByteBufferExtendedCell) cell).getFamilyPosition(), destinationOffset, fLen); 290 } else { 291 ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getFamilyArray(), 292 cell.getFamilyOffset(), fLen); 293 } 294 return destinationOffset + fLen; 295 } 296 297 /** 298 * Copies the qualifier to the given byte[] 299 * @param cell the cell whose qualifier has to be copied 300 * @param destination the destination byte[] to which the qualifier has to be copied 301 * @param destinationOffset the offset in the destination byte[] 302 * @return the offset of the byte[] after the copy has happened 303 */ 304 public static int copyQualifierTo(Cell cell, byte[] destination, int destinationOffset) { 305 int qlen = cell.getQualifierLength(); 306 if (cell instanceof ByteBufferExtendedCell) { 307 ByteBufferUtils.copyFromBufferToArray(destination, 308 ((ByteBufferExtendedCell) cell).getQualifierByteBuffer(), 309 ((ByteBufferExtendedCell) cell).getQualifierPosition(), destinationOffset, qlen); 310 } else { 311 System.arraycopy(cell.getQualifierArray(), cell.getQualifierOffset(), destination, 312 destinationOffset, qlen); 313 } 314 return destinationOffset + qlen; 315 } 316 317 /** 318 * Copies the qualifier to the given bytebuffer 319 * @param cell the cell whose qualifier has to be copied 320 * @param destination the destination bytebuffer to which the qualifier has to be copied 321 * @param destinationOffset the offset in the destination bytebuffer 322 * @return the offset of the bytebuffer after the copy has happened 323 */ 324 public static int copyQualifierTo(Cell cell, ByteBuffer destination, int destinationOffset) { 325 int qlen = cell.getQualifierLength(); 326 if (cell instanceof ByteBufferExtendedCell) { 327 ByteBufferUtils.copyFromBufferToBuffer( 328 ((ByteBufferExtendedCell) cell).getQualifierByteBuffer(), 329 destination, ((ByteBufferExtendedCell) cell).getQualifierPosition(), 330 destinationOffset, qlen); 331 } else { 332 ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, 333 cell.getQualifierArray(), cell.getQualifierOffset(), qlen); 334 } 335 return destinationOffset + qlen; 336 } 337 338 /** 339 * Copies the value to the given byte[] 340 * @param cell the cell whose value has to be copied 341 * @param destination the destination byte[] to which the value has to be copied 342 * @param destinationOffset the offset in the destination byte[] 343 * @return the offset of the byte[] after the copy has happened 344 */ 345 public static int copyValueTo(Cell cell, byte[] destination, int destinationOffset) { 346 int vlen = cell.getValueLength(); 347 if (cell instanceof ByteBufferExtendedCell) { 348 ByteBufferUtils.copyFromBufferToArray(destination, 349 ((ByteBufferExtendedCell) cell).getValueByteBuffer(), 350 ((ByteBufferExtendedCell) cell).getValuePosition(), destinationOffset, vlen); 351 } else { 352 System.arraycopy(cell.getValueArray(), cell.getValueOffset(), destination, destinationOffset, 353 vlen); 354 } 355 return destinationOffset + vlen; 356 } 357 358 /** 359 * Copies the value to the given bytebuffer 360 * @param cell the cell whose value has to be copied 361 * @param destination the destination bytebuffer to which the value has to be copied 362 * @param destinationOffset the offset in the destination bytebuffer 363 * @return the offset of the bytebuffer after the copy has happened 364 */ 365 public static int copyValueTo(Cell cell, ByteBuffer destination, int destinationOffset) { 366 int vlen = cell.getValueLength(); 367 if (cell instanceof ByteBufferExtendedCell) { 368 ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferExtendedCell) cell).getValueByteBuffer(), 369 destination, ((ByteBufferExtendedCell) cell).getValuePosition(), destinationOffset, vlen); 370 } else { 371 ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getValueArray(), 372 cell.getValueOffset(), vlen); 373 } 374 return destinationOffset + vlen; 375 } 376 377 /** 378 * Copies the tags info into the tag portion of the cell 379 * @param cell 380 * @param destination 381 * @param destinationOffset 382 * @return position after tags 383 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 384 */ 385 @Deprecated 386 public static int copyTagTo(Cell cell, byte[] destination, int destinationOffset) { 387 int tlen = cell.getTagsLength(); 388 if (cell instanceof ByteBufferExtendedCell) { 389 ByteBufferUtils 390 .copyFromBufferToArray(destination, ((ByteBufferExtendedCell) cell).getTagsByteBuffer(), 391 ((ByteBufferExtendedCell) cell).getTagsPosition(), destinationOffset, tlen); 392 } else { 393 System 394 .arraycopy(cell.getTagsArray(), cell.getTagsOffset(), destination, destinationOffset, tlen); 395 } 396 return destinationOffset + tlen; 397 } 398 399 /** 400 * Copies the tags info into the tag portion of the cell 401 * @param cell 402 * @param destination 403 * @param destinationOffset 404 * @return position after tags 405 * @deprecated As of HBase-2.0. Will be removed in 3.0. 406 */ 407 @Deprecated 408 public static int copyTagTo(Cell cell, ByteBuffer destination, int destinationOffset) { 409 int tlen = cell.getTagsLength(); 410 if (cell instanceof ByteBufferExtendedCell) { 411 ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferExtendedCell) cell).getTagsByteBuffer(), 412 destination, ((ByteBufferExtendedCell) cell).getTagsPosition(), destinationOffset, tlen); 413 } else { 414 ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getTagsArray(), 415 cell.getTagsOffset(), tlen); 416 } 417 return destinationOffset + tlen; 418 } 419 420 /********************* misc *************************************/ 421 422 @Private 423 /** 424 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0. 425 */ 426 @Deprecated 427 public static byte getRowByte(Cell cell, int index) { 428 if (cell instanceof ByteBufferExtendedCell) { 429 return ((ByteBufferExtendedCell) cell).getRowByteBuffer() 430 .get(((ByteBufferExtendedCell) cell).getRowPosition() + index); 431 } 432 return cell.getRowArray()[cell.getRowOffset() + index]; 433 } 434 435 /** 436 * @deprecated As of HBase-2.0. Will be removed in 3.0. 437 */ 438 @Deprecated 439 public static ByteBuffer getValueBufferShallowCopy(Cell cell) { 440 ByteBuffer buffer = 441 ByteBuffer.wrap(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); 442 return buffer; 443 } 444 445 /** 446 * @param cell 447 * @return cell's qualifier wrapped into a ByteBuffer. 448 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 449 */ 450 @Deprecated 451 public static ByteBuffer getQualifierBufferShallowCopy(Cell cell) { 452 // No usage of this in code. 453 ByteBuffer buffer = ByteBuffer.wrap(cell.getQualifierArray(), cell.getQualifierOffset(), 454 cell.getQualifierLength()); 455 return buffer; 456 } 457 458 /** 459 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder} 460 * instead 461 */ 462 @Deprecated 463 public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier, 464 final long timestamp, final byte type, final byte[] value) { 465 return ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY) 466 .setRow(row) 467 .setFamily(family) 468 .setQualifier(qualifier) 469 .setTimestamp(timestamp) 470 .setType(type) 471 .setValue(value) 472 .build(); 473 } 474 475 /** 476 * Creates a cell with deep copy of all passed bytes. 477 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder} 478 * instead 479 */ 480 @Deprecated 481 public static Cell createCell(final byte[] rowArray, final int rowOffset, final int rowLength, 482 final byte[] familyArray, final int familyOffset, final int familyLength, 483 final byte[] qualifierArray, final int qualifierOffset, final int qualifierLength) { 484 // See createCell(final byte [] row, final byte [] value) for why we default Maximum type. 485 return ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY) 486 .setRow(rowArray, rowOffset, rowLength) 487 .setFamily(familyArray, familyOffset, familyLength) 488 .setQualifier(qualifierArray, qualifierOffset, qualifierLength) 489 .setTimestamp(HConstants.LATEST_TIMESTAMP) 490 .setType(KeyValue.Type.Maximum.getCode()) 491 .setValue(HConstants.EMPTY_BYTE_ARRAY, 0, HConstants.EMPTY_BYTE_ARRAY.length) 492 .build(); 493 } 494 495 /** 496 * Marked as audience Private as of 1.2.0. 497 * Creating a Cell with a memstoreTS/mvcc is an internal 498 * implementation detail not for public use. 499 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use 500 * {@link ExtendedCellBuilder} instead 501 */ 502 @InterfaceAudience.Private 503 @Deprecated 504 public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier, 505 final long timestamp, final byte type, final byte[] value, final long memstoreTS) { 506 return createCell(row, family, qualifier, timestamp, type, value, null, memstoreTS); 507 } 508 509 /** 510 * Marked as audience Private as of 1.2.0. 511 * Creating a Cell with tags and a memstoreTS/mvcc is an 512 * internal implementation detail not for public use. 513 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use 514 * {@link ExtendedCellBuilder} instead 515 */ 516 @InterfaceAudience.Private 517 @Deprecated 518 public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier, 519 final long timestamp, final byte type, final byte[] value, byte[] tags, 520 final long memstoreTS) { 521 return ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY) 522 .setRow(row) 523 .setFamily(family) 524 .setQualifier(qualifier) 525 .setTimestamp(timestamp) 526 .setType(type) 527 .setValue(value) 528 .setTags(tags) 529 .setSequenceId(memstoreTS) 530 .build(); 531 } 532 533 /** 534 * Marked as audience Private as of 1.2.0. 535 * Creating a Cell with tags is an internal implementation detail not for public use. 536 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use 537 * {@link ExtendedCellBuilder} instead 538 */ 539 @InterfaceAudience.Private 540 @Deprecated 541 public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier, 542 final long timestamp, Type type, final byte[] value, byte[] tags) { 543 return createCell(row, family, qualifier, timestamp, type.getCode(), value, tags, 0); 544 } 545 546 /** 547 * Create a Cell with specific row. Other fields defaulted. 548 * @param row 549 * @return Cell with passed row but all other fields are arbitrary 550 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder} 551 * instead 552 */ 553 @Deprecated 554 public static Cell createCell(final byte[] row) { 555 return createCell(row, HConstants.EMPTY_BYTE_ARRAY); 556 } 557 558 /** 559 * Create a Cell with specific row and value. Other fields are defaulted. 560 * @param row 561 * @param value 562 * @return Cell with passed row and value but all other fields are arbitrary 563 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder} 564 * instead 565 */ 566 @Deprecated 567 public static Cell createCell(final byte[] row, final byte[] value) { 568 // An empty family + empty qualifier + Type.Minimum is used as flag to indicate last on row. 569 // See the CellComparator and KeyValue comparator. Search for compareWithoutRow. 570 // Lets not make a last-on-row key as default but at same time, if you are making a key 571 // without specifying type, etc., flag it as weird by setting type to be Maximum. 572 return createCell(row, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY, 573 HConstants.LATEST_TIMESTAMP, KeyValue.Type.Maximum.getCode(), value); 574 } 575 576 /** 577 * Create a Cell with specific row. Other fields defaulted. 578 * @param row 579 * @param family 580 * @param qualifier 581 * @return Cell with passed row but all other fields are arbitrary 582 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder} 583 * instead 584 */ 585 @Deprecated 586 public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier) { 587 // See above in createCell(final byte [] row, final byte [] value) why we set type to Maximum. 588 return createCell(row, family, qualifier, HConstants.LATEST_TIMESTAMP, 589 KeyValue.Type.Maximum.getCode(), HConstants.EMPTY_BYTE_ARRAY); 590 } 591 592 /** 593 * Note : Now only CPs can create cell with tags using the CP environment 594 * Within CP, use {@link RawCell#createCell(Cell, List)} method instead 595 * @return A new cell which is having the extra tags also added to it. 596 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 597 * 598 */ 599 @Deprecated 600 public static Cell createCell(Cell cell, List<Tag> tags) { 601 return PrivateCellUtil.createCell(cell, tags); 602 } 603 604 /** 605 * Now only CPs can create cell with tags using the CP environment 606 * Within CP, use {@link RawCell#createCell(Cell, List)} method instead 607 * @return A new cell which is having the extra tags also added to it. 608 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 609 */ 610 @Deprecated 611 public static Cell createCell(Cell cell, byte[] tags) { 612 return PrivateCellUtil.createCell(cell, tags); 613 } 614 615 /** 616 * Now only CPs can create cell with tags using the CP environment 617 * Within CP, use {@link RawCell#createCell(Cell, List)} method instead 618 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 619 */ 620 @Deprecated 621 public static Cell createCell(Cell cell, byte[] value, byte[] tags) { 622 return PrivateCellUtil.createCell(cell, value, tags); 623 } 624 625 /** 626 * @param cellScannerables 627 * @return CellScanner interface over <code>cellIterables</code> 628 */ 629 public static CellScanner 630 createCellScanner(final List<? extends CellScannable> cellScannerables) { 631 return new CellScanner() { 632 private final Iterator<? extends CellScannable> iterator = cellScannerables.iterator(); 633 private CellScanner cellScanner = null; 634 635 @Override 636 public Cell current() { 637 return this.cellScanner != null ? this.cellScanner.current() : null; 638 } 639 640 @Override 641 public boolean advance() throws IOException { 642 while (true) { 643 if (this.cellScanner == null) { 644 if (!this.iterator.hasNext()) return false; 645 this.cellScanner = this.iterator.next().cellScanner(); 646 } 647 if (this.cellScanner.advance()) return true; 648 this.cellScanner = null; 649 } 650 } 651 }; 652 } 653 654 /** 655 * @param cellIterable 656 * @return CellScanner interface over <code>cellIterable</code> 657 */ 658 public static CellScanner createCellScanner(final Iterable<Cell> cellIterable) { 659 if (cellIterable == null) return null; 660 return createCellScanner(cellIterable.iterator()); 661 } 662 663 /** 664 * @param cells 665 * @return CellScanner interface over <code>cellIterable</code> or null if <code>cells</code> is 666 * null 667 */ 668 public static CellScanner createCellScanner(final Iterator<Cell> cells) { 669 if (cells == null) return null; 670 return new CellScanner() { 671 private final Iterator<Cell> iterator = cells; 672 private Cell current = null; 673 674 @Override 675 public Cell current() { 676 return this.current; 677 } 678 679 @Override 680 public boolean advance() { 681 boolean hasNext = this.iterator.hasNext(); 682 this.current = hasNext ? this.iterator.next() : null; 683 return hasNext; 684 } 685 }; 686 } 687 688 /** 689 * @param cellArray 690 * @return CellScanner interface over <code>cellArray</code> 691 */ 692 public static CellScanner createCellScanner(final Cell[] cellArray) { 693 return new CellScanner() { 694 private final Cell[] cells = cellArray; 695 private int index = -1; 696 697 @Override 698 public Cell current() { 699 if (cells == null) return null; 700 return (index < 0) ? null : this.cells[index]; 701 } 702 703 @Override 704 public boolean advance() { 705 if (cells == null) return false; 706 return ++index < this.cells.length; 707 } 708 }; 709 } 710 711 /** 712 * Flatten the map of cells out under the CellScanner 713 * @param map Map of Cell Lists; for example, the map of families to Cells that is used inside 714 * Put, etc., keeping Cells organized by family. 715 * @return CellScanner interface over <code>cellIterable</code> 716 */ 717 public static CellScanner createCellScanner(final NavigableMap<byte[], List<Cell>> map) { 718 return new CellScanner() { 719 private final Iterator<Entry<byte[], List<Cell>>> entries = map.entrySet().iterator(); 720 private Iterator<Cell> currentIterator = null; 721 private Cell currentCell; 722 723 @Override 724 public Cell current() { 725 return this.currentCell; 726 } 727 728 @Override 729 public boolean advance() { 730 while (true) { 731 if (this.currentIterator == null) { 732 if (!this.entries.hasNext()) return false; 733 this.currentIterator = this.entries.next().getValue().iterator(); 734 } 735 if (this.currentIterator.hasNext()) { 736 this.currentCell = this.currentIterator.next(); 737 return true; 738 } 739 this.currentCell = null; 740 this.currentIterator = null; 741 } 742 } 743 }; 744 } 745 746 /** 747 * @param left 748 * @param right 749 * @return True if the rows in <code>left</code> and <code>right</code> Cells match 750 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Instead use 751 * {@link #matchingRows(Cell, Cell)} 752 */ 753 @Deprecated 754 public static boolean matchingRow(final Cell left, final Cell right) { 755 return matchingRows(left, right); 756 } 757 758 /** 759 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Instead use 760 * {@link #matchingRows(Cell, byte[])} 761 */ 762 @Deprecated 763 public static boolean matchingRow(final Cell left, final byte[] buf) { 764 return matchingRows(left, buf); 765 } 766 767 public static boolean matchingRows(final Cell left, final byte[] buf) { 768 if (buf == null) { 769 return left.getRowLength() == 0; 770 } 771 return PrivateCellUtil.matchingRows(left, buf, 0, buf.length); 772 } 773 774 /** 775 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Instead use 776 * {@link #matchingRows(Cell, Cell)} 777 * @return true if the row is matching 778 */ 779 @Deprecated 780 public static boolean matchingRow(final Cell left, final byte[] buf, final int offset, 781 final int length) { 782 if (left instanceof ByteBufferExtendedCell) { 783 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getRowByteBuffer(), 784 ((ByteBufferExtendedCell) left).getRowPosition(), left.getRowLength(), buf, offset, length); 785 } 786 return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), buf, offset, 787 length); 788 } 789 790 public static boolean matchingFamily(final Cell left, final Cell right) { 791 byte lfamlength = left.getFamilyLength(); 792 byte rfamlength = right.getFamilyLength(); 793 return matchingFamily(left, lfamlength, right, rfamlength); 794 } 795 796 public static boolean matchingFamily(final Cell left, final byte lfamlength, final Cell right, 797 final byte rfamlength) { 798 if (left instanceof ByteBufferExtendedCell && right instanceof ByteBufferExtendedCell) { 799 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getFamilyByteBuffer(), 800 ((ByteBufferExtendedCell) left).getFamilyPosition(), lfamlength, 801 ((ByteBufferExtendedCell) right).getFamilyByteBuffer(), 802 ((ByteBufferExtendedCell) right).getFamilyPosition(), rfamlength); 803 } 804 if (left instanceof ByteBufferExtendedCell) { 805 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getFamilyByteBuffer(), 806 ((ByteBufferExtendedCell) left).getFamilyPosition(), lfamlength, right.getFamilyArray(), 807 right.getFamilyOffset(), rfamlength); 808 } 809 if (right instanceof ByteBufferExtendedCell) { 810 return ByteBufferUtils.equals(((ByteBufferExtendedCell) right).getFamilyByteBuffer(), 811 ((ByteBufferExtendedCell) right).getFamilyPosition(), rfamlength, left.getFamilyArray(), 812 left.getFamilyOffset(), lfamlength); 813 } 814 return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), lfamlength, 815 right.getFamilyArray(), right.getFamilyOffset(), rfamlength); 816 } 817 818 public static boolean matchingFamily(final Cell left, final byte[] buf) { 819 if (buf == null) { 820 return left.getFamilyLength() == 0; 821 } 822 return PrivateCellUtil.matchingFamily(left, buf, 0, buf.length); 823 } 824 825 /** 826 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 827 */ 828 @Deprecated 829 public static boolean matchingFamily(final Cell left, final byte[] buf, final int offset, 830 final int length) { 831 if (left instanceof ByteBufferExtendedCell) { 832 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getFamilyByteBuffer(), 833 ((ByteBufferExtendedCell) left).getFamilyPosition(), left.getFamilyLength(), buf, offset, 834 length); 835 } 836 return Bytes 837 .equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), buf, offset, 838 length); 839 } 840 841 public static boolean matchingQualifier(final Cell left, final Cell right) { 842 int lqlength = left.getQualifierLength(); 843 int rqlength = right.getQualifierLength(); 844 return matchingQualifier(left, lqlength, right, rqlength); 845 } 846 847 private static boolean matchingQualifier(final Cell left, final int lqlength, final Cell right, 848 final int rqlength) { 849 if (left instanceof ByteBufferExtendedCell && right instanceof ByteBufferExtendedCell) { 850 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getQualifierByteBuffer(), 851 ((ByteBufferExtendedCell) left).getQualifierPosition(), lqlength, 852 ((ByteBufferExtendedCell) right).getQualifierByteBuffer(), 853 ((ByteBufferExtendedCell) right).getQualifierPosition(), rqlength); 854 } 855 if (left instanceof ByteBufferExtendedCell) { 856 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getQualifierByteBuffer(), 857 ((ByteBufferExtendedCell) left).getQualifierPosition(), lqlength, right.getQualifierArray(), 858 right.getQualifierOffset(), rqlength); 859 } 860 if (right instanceof ByteBufferExtendedCell) { 861 return ByteBufferUtils.equals(((ByteBufferExtendedCell) right).getQualifierByteBuffer(), 862 ((ByteBufferExtendedCell) right).getQualifierPosition(), rqlength, left.getQualifierArray(), 863 left.getQualifierOffset(), lqlength); 864 } 865 return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), lqlength, 866 right.getQualifierArray(), right.getQualifierOffset(), rqlength); 867 } 868 869 /** 870 * Finds if the qualifier part of the cell and the KV serialized byte[] are equal 871 * @param left 872 * @param buf the serialized keyvalue format byte[] 873 * @return true if the qualifier matches, false otherwise 874 */ 875 public static boolean matchingQualifier(final Cell left, final byte[] buf) { 876 if (buf == null) { 877 return left.getQualifierLength() == 0; 878 } 879 return PrivateCellUtil.matchingQualifier(left, buf, 0, buf.length); 880 } 881 882 /** 883 * Finds if the qualifier part of the cell and the KV serialized byte[] are equal 884 * @param left 885 * @param buf the serialized keyvalue format byte[] 886 * @param offset the offset of the qualifier in the byte[] 887 * @param length the length of the qualifier in the byte[] 888 * @return true if the qualifier matches, false otherwise 889 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 890 */ 891 @Deprecated 892 public static boolean matchingQualifier(final Cell left, final byte[] buf, final int offset, 893 final int length) { 894 if (buf == null) { 895 return left.getQualifierLength() == 0; 896 } 897 if (left instanceof ByteBufferExtendedCell) { 898 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getQualifierByteBuffer(), 899 ((ByteBufferExtendedCell) left).getQualifierPosition(), left.getQualifierLength(), buf, 900 offset, length); 901 } 902 return Bytes 903 .equals(left.getQualifierArray(), left.getQualifierOffset(), left.getQualifierLength(), buf, 904 offset, length); 905 } 906 907 public static boolean matchingColumn(final Cell left, final byte[] fam, final byte[] qual) { 908 return matchingFamily(left, fam) && matchingQualifier(left, qual); 909 } 910 911 /** 912 * @return True if matching column family and the qualifier starts with <code>qual</code> 913 */ 914 public static boolean matchingColumnFamilyAndQualifierPrefix(final Cell left, final byte[] fam, 915 final byte[] qual) { 916 return matchingFamily(left, fam) && PrivateCellUtil.qualifierStartsWith(left, qual); 917 } 918 919 /** 920 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 921 */ 922 @Deprecated 923 public static boolean matchingColumn(final Cell left, final byte[] fam, final int foffset, 924 final int flength, final byte[] qual, final int qoffset, final int qlength) { 925 if (!PrivateCellUtil.matchingFamily(left, fam, foffset, flength)) return false; 926 return PrivateCellUtil.matchingQualifier(left, qual, qoffset, qlength); 927 } 928 929 public static boolean matchingColumn(final Cell left, final Cell right) { 930 if (!matchingFamily(left, right)) return false; 931 return matchingQualifier(left, right); 932 } 933 934 private static boolean matchingColumn(final Cell left, final byte lFamLen, final int lQualLength, 935 final Cell right, final byte rFamLen, final int rQualLength) { 936 if (!matchingFamily(left, lFamLen, right, rFamLen)) { 937 return false; 938 } 939 return matchingQualifier(left, lQualLength, right, rQualLength); 940 } 941 942 public static boolean matchingValue(final Cell left, final Cell right) { 943 return PrivateCellUtil.matchingValue(left, right, left.getValueLength(), 944 right.getValueLength()); 945 } 946 947 public static boolean matchingValue(final Cell left, final byte[] buf) { 948 if (left instanceof ByteBufferExtendedCell) { 949 return ByteBufferUtils.compareTo(((ByteBufferExtendedCell) left).getValueByteBuffer(), 950 ((ByteBufferExtendedCell) left).getValuePosition(), left.getValueLength(), buf, 0, 951 buf.length) == 0; 952 } 953 return Bytes.equals(left.getValueArray(), left.getValueOffset(), left.getValueLength(), buf, 0, 954 buf.length); 955 } 956 957 public static boolean matchingTags(final Cell left, final Cell right) { 958 return PrivateCellUtil.matchingTags(left, right, left.getTagsLength(), right.getTagsLength()); 959 } 960 961 /** 962 * @return True if a delete type, a {@link KeyValue.Type#Delete} or a {KeyValue.Type#DeleteFamily} 963 * or a {@link KeyValue.Type#DeleteColumn} KeyValue type. 964 */ 965 @SuppressWarnings("deprecation") 966 public static boolean isDelete(final Cell cell) { 967 return PrivateCellUtil.isDelete(cell.getTypeByte()); 968 } 969 970 /** 971 * @return True if a delete type, a {@link KeyValue.Type#Delete} or a {KeyValue.Type#DeleteFamily} 972 * or a {@link KeyValue.Type#DeleteColumn} KeyValue type. 973 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 974 */ 975 @Deprecated 976 public static boolean isDelete(final byte type) { 977 return Type.Delete.getCode() <= type && type <= Type.DeleteFamily.getCode(); 978 } 979 980 /** 981 * @return True if this cell is a {@link KeyValue.Type#Delete} type. 982 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 983 */ 984 @Deprecated 985 public static boolean isDeleteType(Cell cell) { 986 return cell.getTypeByte() == Type.Delete.getCode(); 987 } 988 989 /** 990 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 991 */ 992 @Deprecated 993 public static boolean isDeleteFamily(final Cell cell) { 994 return cell.getTypeByte() == Type.DeleteFamily.getCode(); 995 } 996 997 /** 998 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 999 */ 1000 @Deprecated 1001 public static boolean isDeleteFamilyVersion(final Cell cell) { 1002 return cell.getTypeByte() == Type.DeleteFamilyVersion.getCode(); 1003 } 1004 1005 /** 1006 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 1007 */ 1008 @Deprecated 1009 public static boolean isDeleteColumns(final Cell cell) { 1010 return cell.getTypeByte() == Type.DeleteColumn.getCode(); 1011 } 1012 1013 /** 1014 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 1015 */ 1016 @Deprecated 1017 public static boolean isDeleteColumnVersion(final Cell cell) { 1018 return cell.getTypeByte() == Type.Delete.getCode(); 1019 } 1020 1021 /** 1022 * @return True if this cell is a delete family or column type. 1023 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 1024 */ 1025 @Deprecated 1026 public static boolean isDeleteColumnOrFamily(Cell cell) { 1027 int t = cell.getTypeByte(); 1028 return t == Type.DeleteColumn.getCode() || t == Type.DeleteFamily.getCode(); 1029 } 1030 1031 /** 1032 * @return True if this cell is a Put. 1033 */ 1034 @SuppressWarnings("deprecation") 1035 public static boolean isPut(Cell cell) { 1036 return cell.getTypeByte() == Type.Put.getCode(); 1037 } 1038 1039 /** 1040 * Estimate based on keyvalue's serialization format in the RPC layer. Note that there is an extra 1041 * SIZEOF_INT added to the size here that indicates the actual length of the cell for cases where 1042 * cell's are serialized in a contiguous format (For eg in RPCs). 1043 * @param cell 1044 * @return Estimate of the <code>cell</code> size in bytes plus an extra SIZEOF_INT indicating the 1045 * actual cell length. 1046 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 1047 */ 1048 @Deprecated 1049 public static int estimatedSerializedSizeOf(final Cell cell) { 1050 if (cell instanceof ExtendedCell) { 1051 return ((ExtendedCell) cell).getSerializedSize(true) + Bytes.SIZEOF_INT; 1052 } 1053 1054 return getSumOfCellElementLengths(cell) + 1055 // Use the KeyValue's infrastructure size presuming that another implementation would have 1056 // same basic cost. 1057 KeyValue.ROW_LENGTH_SIZE + KeyValue.FAMILY_LENGTH_SIZE + 1058 // Serialization is probably preceded by a length (it is in the KeyValueCodec at least). 1059 Bytes.SIZEOF_INT; 1060 } 1061 1062 /** 1063 * @param cell 1064 * @return Sum of the lengths of all the elements in a Cell; does not count in any infrastructure 1065 */ 1066 private static int getSumOfCellElementLengths(final Cell cell) { 1067 return getSumOfCellKeyElementLengths(cell) + cell.getValueLength() + cell.getTagsLength(); 1068 } 1069 1070 /** 1071 * @param cell 1072 * @return Sum of all elements that make up a key; does not include infrastructure, tags or 1073 * values. 1074 */ 1075 private static int getSumOfCellKeyElementLengths(final Cell cell) { 1076 return cell.getRowLength() + cell.getFamilyLength() + cell.getQualifierLength() 1077 + KeyValue.TIMESTAMP_TYPE_SIZE; 1078 } 1079 1080 /** 1081 * Calculates the serialized key size. We always serialize in the KeyValue's serialization format. 1082 * @param cell the cell for which the key size has to be calculated. 1083 * @return the key size 1084 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 1085 */ 1086 @Deprecated 1087 public static int estimatedSerializedSizeOfKey(final Cell cell) { 1088 if (cell instanceof KeyValue) return ((KeyValue) cell).getKeyLength(); 1089 return cell.getRowLength() + cell.getFamilyLength() + cell.getQualifierLength() 1090 + KeyValue.KEY_INFRASTRUCTURE_SIZE; 1091 } 1092 1093 /** 1094 * This is an estimate of the heap space occupied by a cell. When the cell is of type 1095 * {@link HeapSize} we call {@link HeapSize#heapSize()} so cell can give a correct value. In other 1096 * cases we just consider the bytes occupied by the cell components ie. row, CF, qualifier, 1097 * timestamp, type, value and tags. 1098 * @param cell 1099 * @return estimate of the heap space 1100 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 1101 * Use {@link RawCell#getTags()} 1102 */ 1103 @Deprecated 1104 public static long estimatedHeapSizeOf(final Cell cell) { 1105 return cell.heapSize(); 1106 } 1107 1108 /********************* tags *************************************/ 1109 /** 1110 * Util method to iterate through the tags 1111 * @param tags 1112 * @param offset 1113 * @param length 1114 * @return iterator for the tags 1115 * @deprecated As of 2.0.0 and will be removed in 3.0.0 Instead use 1116 * {@link PrivateCellUtil#tagsIterator(Cell)} 1117 */ 1118 @Deprecated 1119 public static Iterator<Tag> tagsIterator(final byte[] tags, final int offset, final int length) { 1120 return new Iterator<Tag>() { 1121 private int pos = offset; 1122 private int endOffset = offset + length - 1; 1123 1124 @Override 1125 public boolean hasNext() { 1126 return this.pos < endOffset; 1127 } 1128 1129 @Override 1130 public Tag next() { 1131 if (hasNext()) { 1132 int curTagLen = Bytes.readAsInt(tags, this.pos, Tag.TAG_LENGTH_SIZE); 1133 Tag tag = new ArrayBackedTag(tags, pos, curTagLen + TAG_LENGTH_SIZE); 1134 this.pos += Bytes.SIZEOF_SHORT + curTagLen; 1135 return tag; 1136 } 1137 return null; 1138 } 1139 1140 @Override 1141 public void remove() { 1142 throw new UnsupportedOperationException(); 1143 } 1144 }; 1145 } 1146 1147 /** 1148 * @param cell The Cell 1149 * @return Tags in the given Cell as a List 1150 * @deprecated As of 2.0.0 and will be removed in 3.0.0 1151 */ 1152 @Deprecated 1153 public static List<Tag> getTags(Cell cell) { 1154 List<Tag> tags = new ArrayList<>(); 1155 Iterator<Tag> tagsItr = PrivateCellUtil.tagsIterator(cell); 1156 while (tagsItr.hasNext()) { 1157 tags.add(tagsItr.next()); 1158 } 1159 return tags; 1160 } 1161 1162 /** 1163 * Retrieve Cell's first tag, matching the passed in type 1164 * @param cell The Cell 1165 * @param type Type of the Tag to retrieve 1166 * @return null if there is no tag of the passed in tag type 1167 * @deprecated As of 2.0.0 and will be removed in HBase-3.0.0 1168 * Use {@link RawCell#getTag(byte)} 1169 */ 1170 @Deprecated 1171 public static Tag getTag(Cell cell, byte type) { 1172 Optional<Tag> tag = PrivateCellUtil.getTag(cell, type); 1173 if (tag.isPresent()) { 1174 return tag.get(); 1175 } else { 1176 return null; 1177 } 1178 } 1179 1180 /** 1181 * Returns true if the first range start1...end1 overlaps with the second range start2...end2, 1182 * assuming the byte arrays represent row keys 1183 * @deprecated As of 2.0.0 and will be removed in 3.0.0 1184 */ 1185 @Deprecated 1186 public static boolean overlappingKeys(final byte[] start1, final byte[] end1, final byte[] start2, 1187 final byte[] end2) { 1188 return (end2.length == 0 || start1.length == 0 || Bytes.compareTo(start1, end2) < 0) 1189 && (end1.length == 0 || start2.length == 0 || Bytes.compareTo(start2, end1) < 0); 1190 } 1191 1192 /** 1193 * Sets the given seqId to the cell. Marked as audience Private as of 1.2.0. Setting a Cell 1194 * sequenceid is an internal implementation detail not for general public use. 1195 * @param cell 1196 * @param seqId 1197 * @throws IOException when the passed cell is not of type {@link ExtendedCell} 1198 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1199 */ 1200 @Deprecated 1201 public static void setSequenceId(Cell cell, long seqId) throws IOException { 1202 PrivateCellUtil.setSequenceId(cell, seqId); 1203 } 1204 1205 /** 1206 * Sets the given timestamp to the cell. 1207 * @param cell 1208 * @param ts 1209 * @throws IOException when the passed cell is not of type {@link ExtendedCell} 1210 * @deprecated As of HBase-2.0. Will be a LimitedPrivate API in HBase-3.0. 1211 */ 1212 @Deprecated 1213 public static void setTimestamp(Cell cell, long ts) throws IOException { 1214 PrivateCellUtil.setTimestamp(cell, ts); 1215 } 1216 1217 /** 1218 * Sets the given timestamp to the cell. 1219 * @param cell 1220 * @param ts buffer containing the timestamp value 1221 * @param tsOffset offset to the new timestamp 1222 * @throws IOException when the passed cell is not of type {@link ExtendedCell} 1223 * @deprecated As of HBase-2.0. Will be a LimitedPrivate API in HBase-3.0. 1224 */ 1225 @Deprecated 1226 public static void setTimestamp(Cell cell, byte[] ts, int tsOffset) throws IOException { 1227 PrivateCellUtil.setTimestamp(cell, Bytes.toLong(ts, tsOffset)); 1228 } 1229 1230 /** 1231 * Sets the given timestamp to the cell iff current timestamp is 1232 * {@link HConstants#LATEST_TIMESTAMP}. 1233 * @param cell 1234 * @param ts 1235 * @return True if cell timestamp is modified. 1236 * @throws IOException when the passed cell is not of type {@link ExtendedCell} 1237 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1238 */ 1239 @Deprecated 1240 public static boolean updateLatestStamp(Cell cell, long ts) throws IOException { 1241 return PrivateCellUtil.updateLatestStamp(cell, ts); 1242 } 1243 1244 /** 1245 * Sets the given timestamp to the cell iff current timestamp is 1246 * {@link HConstants#LATEST_TIMESTAMP}. 1247 * @param cell 1248 * @param ts buffer containing the timestamp value 1249 * @param tsOffset offset to the new timestamp 1250 * @return True if cell timestamp is modified. 1251 * @throws IOException when the passed cell is not of type {@link ExtendedCell} 1252 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1253 */ 1254 @Deprecated 1255 public static boolean updateLatestStamp(Cell cell, byte[] ts, int tsOffset) throws IOException { 1256 return PrivateCellUtil.updateLatestStamp(cell, Bytes.toLong(ts, tsOffset)); 1257 } 1258 1259 /** 1260 * Writes the Cell's key part as it would have serialized in a KeyValue. The format is <2 bytes 1261 * rk len><rk><1 byte cf len><cf><qualifier><8 bytes 1262 * timestamp><1 byte type> 1263 * @param cell 1264 * @param out 1265 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1266 * @throws IOException 1267 */ 1268 @Deprecated 1269 public static void writeFlatKey(Cell cell, DataOutputStream out) throws IOException { 1270 short rowLen = cell.getRowLength(); 1271 byte fLen = cell.getFamilyLength(); 1272 int qLen = cell.getQualifierLength(); 1273 // Using just one if/else loop instead of every time checking before writing every 1274 // component of cell 1275 if (cell instanceof ByteBufferExtendedCell) { 1276 out.writeShort(rowLen); 1277 ByteBufferUtils 1278 .copyBufferToStream((DataOutput) out, ((ByteBufferExtendedCell) cell).getRowByteBuffer(), 1279 ((ByteBufferExtendedCell) cell).getRowPosition(), rowLen); 1280 out.writeByte(fLen); 1281 ByteBufferUtils 1282 .copyBufferToStream((DataOutput) out, ((ByteBufferExtendedCell) cell).getFamilyByteBuffer(), 1283 ((ByteBufferExtendedCell) cell).getFamilyPosition(), fLen); 1284 ByteBufferUtils.copyBufferToStream((DataOutput) out, 1285 ((ByteBufferExtendedCell) cell).getQualifierByteBuffer(), 1286 ((ByteBufferExtendedCell) cell).getQualifierPosition(), qLen); 1287 } else { 1288 out.writeShort(rowLen); 1289 out.write(cell.getRowArray(), cell.getRowOffset(), rowLen); 1290 out.writeByte(fLen); 1291 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), fLen); 1292 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qLen); 1293 } 1294 out.writeLong(cell.getTimestamp()); 1295 out.writeByte(cell.getTypeByte()); 1296 } 1297 1298 /** 1299 * Writes the row from the given cell to the output stream excluding the common prefix 1300 * @param out The dataoutputstream to which the data has to be written 1301 * @param cell The cell whose contents has to be written 1302 * @param rlength the row length 1303 * @throws IOException 1304 * @deprecated As of 2.0. Will be removed in hbase-3.0 1305 */ 1306 @Deprecated 1307 public static void writeRowSkippingBytes(DataOutputStream out, Cell cell, short rlength, 1308 int commonPrefix) throws IOException { 1309 if (cell instanceof ByteBufferExtendedCell) { 1310 ByteBufferUtils 1311 .copyBufferToStream((DataOutput) out, ((ByteBufferExtendedCell) cell).getRowByteBuffer(), 1312 ((ByteBufferExtendedCell) cell).getRowPosition() + commonPrefix, rlength - commonPrefix); 1313 } else { 1314 out.write(cell.getRowArray(), cell.getRowOffset() + commonPrefix, rlength - commonPrefix); 1315 } 1316 } 1317 1318 /** 1319 * @param cell 1320 * @return The Key portion of the passed <code>cell</code> as a String. 1321 */ 1322 public static String getCellKeyAsString(Cell cell) { 1323 return getCellKeyAsString(cell, 1324 c -> Bytes.toStringBinary(c.getRowArray(), c.getRowOffset(), c.getRowLength())); 1325 } 1326 1327 /** 1328 * @param cell the cell to convert 1329 * @param rowConverter used to convert the row of the cell to a string 1330 * @return The Key portion of the passed <code>cell</code> as a String. 1331 */ 1332 public static String getCellKeyAsString(Cell cell, Function<Cell, String> rowConverter) { 1333 StringBuilder sb = new StringBuilder(rowConverter.apply(cell)); 1334 sb.append('/'); 1335 sb.append(cell.getFamilyLength() == 0 ? "" : 1336 Bytes.toStringBinary(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength())); 1337 // KeyValue only added ':' if family is non-null. Do same. 1338 if (cell.getFamilyLength() > 0) sb.append(':'); 1339 sb.append(cell.getQualifierLength() == 0 ? "" : 1340 Bytes.toStringBinary(cell.getQualifierArray(), cell.getQualifierOffset(), 1341 cell.getQualifierLength())); 1342 sb.append('/'); 1343 sb.append(KeyValue.humanReadableTimestamp(cell.getTimestamp())); 1344 sb.append('/'); 1345 sb.append(Type.codeToType(cell.getTypeByte())); 1346 if (!(cell instanceof KeyValue.KeyOnlyKeyValue)) { 1347 sb.append("/vlen="); 1348 sb.append(cell.getValueLength()); 1349 } 1350 sb.append("/seqid="); 1351 sb.append(cell.getSequenceId()); 1352 return sb.toString(); 1353 } 1354 1355 /** 1356 * This method exists just to encapsulate how we serialize keys. To be replaced by a factory that 1357 * we query to figure what the Cell implementation is and then, what serialization engine to use 1358 * and further, how to serialize the key for inclusion in hfile index. TODO. 1359 * @param cell 1360 * @return The key portion of the Cell serialized in the old-school KeyValue way or null if passed 1361 * a null <code>cell</code> 1362 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1363 */ 1364 @Deprecated 1365 public static byte[] getCellKeySerializedAsKeyValueKey(final Cell cell) { 1366 if (cell == null) return null; 1367 byte[] b = new byte[KeyValueUtil.keyLength(cell)]; 1368 KeyValueUtil.appendKeyTo(cell, b, 0); 1369 return b; 1370 } 1371 1372 /** 1373 * Write rowkey excluding the common part. 1374 * @param cell 1375 * @param rLen 1376 * @param commonPrefix 1377 * @param out 1378 * @throws IOException 1379 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1380 */ 1381 @Deprecated 1382 public static void writeRowKeyExcludingCommon(Cell cell, short rLen, int commonPrefix, 1383 DataOutputStream out) throws IOException { 1384 if (commonPrefix == 0) { 1385 out.writeShort(rLen); 1386 } else if (commonPrefix == 1) { 1387 out.writeByte((byte) rLen); 1388 commonPrefix--; 1389 } else { 1390 commonPrefix -= KeyValue.ROW_LENGTH_SIZE; 1391 } 1392 if (rLen > commonPrefix) { 1393 PrivateCellUtil.writeRowSkippingBytes(out, cell, rLen, commonPrefix); 1394 } 1395 } 1396 1397 /** 1398 * Find length of common prefix in keys of the cells, considering key as byte[] if serialized in 1399 * {@link KeyValue}. The key format is <2 bytes rk len><rk><1 byte cf 1400 * len><cf><qualifier><8 bytes timestamp><1 byte type> 1401 * @param c1 the cell 1402 * @param c2 the cell 1403 * @param bypassFamilyCheck when true assume the family bytes same in both cells. Pass it as true 1404 * when dealing with Cells in same CF so as to avoid some checks 1405 * @param withTsType when true check timestamp and type bytes also. 1406 * @return length of common prefix 1407 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1408 */ 1409 @Deprecated 1410 public static int findCommonPrefixInFlatKey(Cell c1, Cell c2, boolean bypassFamilyCheck, 1411 boolean withTsType) { 1412 // Compare the 2 bytes in RK length part 1413 short rLen1 = c1.getRowLength(); 1414 short rLen2 = c2.getRowLength(); 1415 int commonPrefix = KeyValue.ROW_LENGTH_SIZE; 1416 if (rLen1 != rLen2) { 1417 // early out when the RK length itself is not matching 1418 return ByteBufferUtils 1419 .findCommonPrefix(Bytes.toBytes(rLen1), 0, KeyValue.ROW_LENGTH_SIZE, Bytes.toBytes(rLen2), 1420 0, KeyValue.ROW_LENGTH_SIZE); 1421 } 1422 // Compare the RKs 1423 int rkCommonPrefix = 0; 1424 if (c1 instanceof ByteBufferExtendedCell && c2 instanceof ByteBufferExtendedCell) { 1425 rkCommonPrefix = ByteBufferUtils 1426 .findCommonPrefix(((ByteBufferExtendedCell) c1).getRowByteBuffer(), 1427 ((ByteBufferExtendedCell) c1).getRowPosition(), rLen1, 1428 ((ByteBufferExtendedCell) c2).getRowByteBuffer(), 1429 ((ByteBufferExtendedCell) c2).getRowPosition(), rLen2); 1430 } else { 1431 // There cannot be a case where one cell is BBCell and other is KeyValue. This flow comes 1432 // either 1433 // in flush or compactions. In flushes both cells are KV and in case of compaction it will be 1434 // either 1435 // KV or BBCell 1436 rkCommonPrefix = ByteBufferUtils 1437 .findCommonPrefix(c1.getRowArray(), c1.getRowOffset(), rLen1, c2.getRowArray(), 1438 c2.getRowOffset(), rLen2); 1439 } 1440 commonPrefix += rkCommonPrefix; 1441 if (rkCommonPrefix != rLen1) { 1442 // Early out when RK is not fully matching. 1443 return commonPrefix; 1444 } 1445 // Compare 1 byte CF length part 1446 byte fLen1 = c1.getFamilyLength(); 1447 if (bypassFamilyCheck) { 1448 // This flag will be true when caller is sure that the family will be same for both the cells 1449 // Just make commonPrefix to increment by the family part 1450 commonPrefix += KeyValue.FAMILY_LENGTH_SIZE + fLen1; 1451 } else { 1452 byte fLen2 = c2.getFamilyLength(); 1453 if (fLen1 != fLen2) { 1454 // early out when the CF length itself is not matching 1455 return commonPrefix; 1456 } 1457 // CF lengths are same so there is one more byte common in key part 1458 commonPrefix += KeyValue.FAMILY_LENGTH_SIZE; 1459 // Compare the CF names 1460 int fCommonPrefix; 1461 if (c1 instanceof ByteBufferExtendedCell && c2 instanceof ByteBufferExtendedCell) { 1462 fCommonPrefix = ByteBufferUtils 1463 .findCommonPrefix(((ByteBufferExtendedCell) c1).getFamilyByteBuffer(), 1464 ((ByteBufferExtendedCell) c1).getFamilyPosition(), fLen1, 1465 ((ByteBufferExtendedCell) c2).getFamilyByteBuffer(), 1466 ((ByteBufferExtendedCell) c2).getFamilyPosition(), fLen2); 1467 } else { 1468 fCommonPrefix = ByteBufferUtils 1469 .findCommonPrefix(c1.getFamilyArray(), c1.getFamilyOffset(), fLen1, c2.getFamilyArray(), 1470 c2.getFamilyOffset(), fLen2); 1471 } 1472 commonPrefix += fCommonPrefix; 1473 if (fCommonPrefix != fLen1) { 1474 return commonPrefix; 1475 } 1476 } 1477 // Compare the Qualifiers 1478 int qLen1 = c1.getQualifierLength(); 1479 int qLen2 = c2.getQualifierLength(); 1480 int qCommon; 1481 if (c1 instanceof ByteBufferExtendedCell && c2 instanceof ByteBufferExtendedCell) { 1482 qCommon = ByteBufferUtils 1483 .findCommonPrefix(((ByteBufferExtendedCell) c1).getQualifierByteBuffer(), 1484 ((ByteBufferExtendedCell) c1).getQualifierPosition(), qLen1, 1485 ((ByteBufferExtendedCell) c2).getQualifierByteBuffer(), 1486 ((ByteBufferExtendedCell) c2).getQualifierPosition(), qLen2); 1487 } else { 1488 qCommon = ByteBufferUtils 1489 .findCommonPrefix(c1.getQualifierArray(), c1.getQualifierOffset(), qLen1, 1490 c2.getQualifierArray(), c2.getQualifierOffset(), qLen2); 1491 } 1492 commonPrefix += qCommon; 1493 if (!withTsType || Math.max(qLen1, qLen2) != qCommon) { 1494 return commonPrefix; 1495 } 1496 // Compare the timestamp parts 1497 int tsCommonPrefix = ByteBufferUtils 1498 .findCommonPrefix(Bytes.toBytes(c1.getTimestamp()), 0, KeyValue.TIMESTAMP_SIZE, 1499 Bytes.toBytes(c2.getTimestamp()), 0, KeyValue.TIMESTAMP_SIZE); 1500 commonPrefix += tsCommonPrefix; 1501 if (tsCommonPrefix != KeyValue.TIMESTAMP_SIZE) { 1502 return commonPrefix; 1503 } 1504 // Compare the type 1505 if (c1.getTypeByte() == c2.getTypeByte()) { 1506 commonPrefix += KeyValue.TYPE_SIZE; 1507 } 1508 return commonPrefix; 1509 } 1510 1511 /** Returns a string representation of the cell */ 1512 public static String toString(Cell cell, boolean verbose) { 1513 if (cell == null) { 1514 return ""; 1515 } 1516 StringBuilder builder = new StringBuilder(); 1517 String keyStr = getCellKeyAsString(cell); 1518 1519 String tag = null; 1520 String value = null; 1521 if (verbose) { 1522 // TODO: pretty print tags as well 1523 if (cell.getTagsLength() > 0) { 1524 tag = Bytes.toStringBinary(cell.getTagsArray(), cell.getTagsOffset(), cell.getTagsLength()); 1525 } 1526 if (!(cell instanceof KeyValue.KeyOnlyKeyValue)) { 1527 value = Bytes.toStringBinary(cell.getValueArray(), cell.getValueOffset(), 1528 cell.getValueLength()); 1529 } 1530 } 1531 1532 builder.append(keyStr); 1533 if (tag != null && !tag.isEmpty()) { 1534 builder.append("/").append(tag); 1535 } 1536 if (value != null) { 1537 builder.append("/").append(value); 1538 } 1539 1540 return builder.toString(); 1541 } 1542 1543 /***************** special cases ****************************/ 1544 1545 /** 1546 * special case for Cell.equals 1547 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1548 */ 1549 @Deprecated 1550 public static boolean equalsIgnoreMvccVersion(Cell a, Cell b) { 1551 // row 1552 boolean res = matchingRows(a, b); 1553 if (!res) return res; 1554 1555 // family 1556 res = matchingColumn(a, b); 1557 if (!res) return res; 1558 1559 // timestamp: later sorts first 1560 if (!matchingTimestamp(a, b)) return false; 1561 1562 // type 1563 int c = (0xff & b.getTypeByte()) - (0xff & a.getTypeByte()); 1564 if (c != 0) return false; 1565 else return true; 1566 } 1567 1568 /**************** equals ****************************/ 1569 1570 public static boolean equals(Cell a, Cell b) { 1571 return matchingRows(a, b) && matchingFamily(a, b) && matchingQualifier(a, b) 1572 && matchingTimestamp(a, b) && PrivateCellUtil.matchingType(a, b); 1573 } 1574 1575 public static boolean matchingTimestamp(Cell a, Cell b) { 1576 return CellComparator.getInstance().compareTimestamps(a.getTimestamp(), b.getTimestamp()) == 0; 1577 } 1578 1579 /** 1580 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1581 */ 1582 @Deprecated 1583 public static boolean matchingType(Cell a, Cell b) { 1584 return a.getTypeByte() == b.getTypeByte(); 1585 } 1586 1587 /** 1588 * Compares the row of two keyvalues for equality 1589 * @param left 1590 * @param right 1591 * @return True if rows match. 1592 */ 1593 public static boolean matchingRows(final Cell left, final Cell right) { 1594 short lrowlength = left.getRowLength(); 1595 short rrowlength = right.getRowLength(); 1596 return matchingRows(left, lrowlength, right, rrowlength); 1597 } 1598 1599 public static boolean matchingRows(final Cell left, final short lrowlength, final Cell right, 1600 final short rrowlength) { 1601 if (lrowlength != rrowlength) return false; 1602 if (left instanceof ByteBufferExtendedCell && right instanceof ByteBufferExtendedCell) { 1603 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getRowByteBuffer(), 1604 ((ByteBufferExtendedCell) left).getRowPosition(), lrowlength, 1605 ((ByteBufferExtendedCell) right).getRowByteBuffer(), 1606 ((ByteBufferExtendedCell) right).getRowPosition(), rrowlength); 1607 } 1608 if (left instanceof ByteBufferExtendedCell) { 1609 return ByteBufferUtils.equals(((ByteBufferExtendedCell) left).getRowByteBuffer(), 1610 ((ByteBufferExtendedCell) left).getRowPosition(), lrowlength, right.getRowArray(), 1611 right.getRowOffset(), rrowlength); 1612 } 1613 if (right instanceof ByteBufferExtendedCell) { 1614 return ByteBufferUtils.equals(((ByteBufferExtendedCell) right).getRowByteBuffer(), 1615 ((ByteBufferExtendedCell) right).getRowPosition(), rrowlength, left.getRowArray(), 1616 left.getRowOffset(), lrowlength); 1617 } 1618 return Bytes.equals(left.getRowArray(), left.getRowOffset(), lrowlength, right.getRowArray(), 1619 right.getRowOffset(), rrowlength); 1620 } 1621 1622 /** 1623 * Compares the row and column of two keyvalues for equality 1624 * @param left 1625 * @param right 1626 * @return True if same row and column. 1627 */ 1628 public static boolean matchingRowColumn(final Cell left, final Cell right) { 1629 short lrowlength = left.getRowLength(); 1630 short rrowlength = right.getRowLength(); 1631 // match length 1632 if (lrowlength != rrowlength) { 1633 return false; 1634 } 1635 1636 byte lfamlength = left.getFamilyLength(); 1637 byte rfamlength = right.getFamilyLength(); 1638 if (lfamlength != rfamlength) { 1639 return false; 1640 } 1641 1642 int lqlength = left.getQualifierLength(); 1643 int rqlength = right.getQualifierLength(); 1644 if (lqlength != rqlength) { 1645 return false; 1646 } 1647 1648 if (!matchingRows(left, lrowlength, right, rrowlength)) { 1649 return false; 1650 } 1651 return matchingColumn(left, lfamlength, lqlength, right, rfamlength, rqlength); 1652 } 1653 1654 public static boolean matchingRowColumnBytes(final Cell left, final Cell right) { 1655 int lrowlength = left.getRowLength(); 1656 int rrowlength = right.getRowLength(); 1657 int lfamlength = left.getFamilyLength(); 1658 int rfamlength = right.getFamilyLength(); 1659 int lqlength = left.getQualifierLength(); 1660 int rqlength = right.getQualifierLength(); 1661 1662 // match length 1663 if ((lrowlength != rrowlength) || (lfamlength != rfamlength) || (lqlength != rqlength)) { 1664 return false; 1665 } 1666 1667 // match row 1668 if (!Bytes.equals(left.getRowArray(), left.getRowOffset(), lrowlength, right.getRowArray(), 1669 right.getRowOffset(), rrowlength)) { 1670 return false; 1671 } 1672 //match family 1673 if (!Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), lfamlength, 1674 right.getFamilyArray(), right.getFamilyOffset(), rfamlength)) { 1675 return false; 1676 } 1677 //match qualifier 1678 return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), 1679 lqlength, right.getQualifierArray(), right.getQualifierOffset(), 1680 rqlength); 1681 } 1682 1683 /** 1684 * Compares the cell's qualifier with the given byte[] 1685 * @param left the cell for which the qualifier has to be compared 1686 * @param right the byte[] having the qualifier 1687 * @param rOffset the offset of the qualifier 1688 * @param rLength the length of the qualifier 1689 * @return greater than 0 if left cell's qualifier is bigger than byte[], lesser than 0 if left 1690 * cell's qualifier is lesser than byte[] and 0 otherwise 1691 */ 1692 public final static int compareQualifiers(Cell left, byte[] right, int rOffset, int rLength) { 1693 if (left instanceof ByteBufferExtendedCell) { 1694 return ByteBufferUtils.compareTo(((ByteBufferExtendedCell) left).getQualifierByteBuffer(), 1695 ((ByteBufferExtendedCell) left).getQualifierPosition(), 1696 left.getQualifierLength(), right, rOffset, rLength); 1697 } 1698 return Bytes.compareTo(left.getQualifierArray(), left.getQualifierOffset(), 1699 left.getQualifierLength(), right, rOffset, rLength); 1700 } 1701 1702 /** 1703 * Used when a cell needs to be compared with a key byte[] such as cases of finding the index from 1704 * the index block, bloom keys from the bloom blocks This byte[] is expected to be serialized in 1705 * the KeyValue serialization format If the KeyValue (Cell's) serialization format changes this 1706 * method cannot be used. 1707 * @param comparator the cell comparator 1708 * @param left the cell to be compared 1709 * @param key the serialized key part of a KeyValue 1710 * @param offset the offset in the key byte[] 1711 * @param length the length of the key byte[] 1712 * @return an int greater than 0 if left is greater than right lesser than 0 if left is lesser 1713 * than right equal to 0 if left is equal to right 1714 * @deprecated As of HBase-2.0. Will be removed in HBase-3.0 1715 */ 1716 @InterfaceAudience.Private 1717 @Deprecated 1718 public static final int compare(CellComparator comparator, Cell left, byte[] key, int offset, 1719 int length) { 1720 // row 1721 short rrowlength = Bytes.toShort(key, offset); 1722 int c = comparator.compareRows(left, key, offset + Bytes.SIZEOF_SHORT, rrowlength); 1723 if (c != 0) return c; 1724 1725 // Compare the rest of the two KVs without making any assumptions about 1726 // the common prefix. This function will not compare rows anyway, so we 1727 // don't need to tell it that the common prefix includes the row. 1728 return PrivateCellUtil.compareWithoutRow(comparator, left, key, offset, length, rrowlength); 1729 } 1730 1731 /** 1732 * Compares the cell's family with the given byte[] 1733 * @param left the cell for which the family has to be compared 1734 * @param right the byte[] having the family 1735 * @param roffset the offset of the family 1736 * @param rlength the length of the family 1737 * @return greater than 0 if left cell's family is bigger than byte[], lesser than 0 if left 1738 * cell's family is lesser than byte[] and 0 otherwise 1739 */ 1740 public final static int compareFamilies(Cell left, byte[] right, int roffset, int rlength) { 1741 if (left instanceof ByteBufferExtendedCell) { 1742 return ByteBufferUtils.compareTo(((ByteBufferExtendedCell) left).getFamilyByteBuffer(), 1743 ((ByteBufferExtendedCell) left).getFamilyPosition(), left.getFamilyLength(), right, roffset, 1744 rlength); 1745 } 1746 return Bytes.compareTo(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), 1747 right, roffset, rlength); 1748 } 1749 1750 /** 1751 * Compares the cell's column (family and qualifier) with the given byte[] 1752 * @param left the cell for which the column has to be compared 1753 * @param right the byte[] having the column 1754 * @param rfoffset the offset of the family 1755 * @param rflength the length of the family 1756 * @param rqoffset the offset of the qualifier 1757 * @param rqlength the length of the qualifier 1758 * @return greater than 0 if left cell's column is bigger than byte[], lesser than 0 if left 1759 * cell's column is lesser than byte[] and 0 otherwise 1760 */ 1761 public final static int compareColumns(Cell left, byte[] right, int rfoffset, int rflength, 1762 int rqoffset, int rqlength) { 1763 int diff = compareFamilies(left, right, rfoffset, rflength); 1764 if (diff != 0) return diff; 1765 return compareQualifiers(left, right, rqoffset, rqlength); 1766 } 1767}