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