Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 92C002004F5 for ; Fri, 1 Sep 2017 17:13:59 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 9147916D3C7; Fri, 1 Sep 2017 15:13:59 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id B196416D3B9 for ; Fri, 1 Sep 2017 17:13:57 +0200 (CEST) Received: (qmail 10411 invoked by uid 500); 1 Sep 2017 15:13:55 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 8721 invoked by uid 99); 1 Sep 2017 15:13:54 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 01 Sep 2017 15:13:54 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 0C399F5640; Fri, 1 Sep 2017 15:13:52 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: git-site-role@apache.org To: commits@hbase.apache.org Date: Fri, 01 Sep 2017 15:13:57 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [06/51] [partial] hbase-site git commit: Published site at . archived-at: Fri, 01 Sep 2017 15:13:59 -0000 http://git-wip-us.apache.org/repos/asf/hbase-site/blob/7ebe345d/devapidocs/src-html/org/apache/hadoop/hbase/CellUtil.FirstOnRowColByteBufferCell.html ---------------------------------------------------------------------- diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/CellUtil.FirstOnRowColByteBufferCell.html b/devapidocs/src-html/org/apache/hadoop/hbase/CellUtil.FirstOnRowColByteBufferCell.html index 6b0729b..9adaf3b 100644 --- a/devapidocs/src-html/org/apache/hadoop/hbase/CellUtil.FirstOnRowColByteBufferCell.html +++ b/devapidocs/src-html/org/apache/hadoop/hbase/CellUtil.FirstOnRowColByteBufferCell.html @@ -1559,1681 +1559,1662 @@ 1551 }; 1552 } 1553 -1554 private static final Iterator<Tag> EMPTY_TAGS_ITR = new Iterator<Tag>() { -1555 @Override -1556 public boolean hasNext() { -1557 return false; -1558 } -1559 -1560 @Override -1561 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="IT_NO_SUCH_ELEMENT", -1562 justification="Intentional") -1563 public Tag next() { -1564 return null; +1554 /** +1555 * Util method to iterate through the tags in the given cell. +1556 * +1557 * @param cell The Cell over which tags iterator is needed. +1558 * @return iterator for the tags +1559 */ +1560 public static Iterator<Tag> tagsIterator(final Cell cell) { +1561 final int tagsLength = cell.getTagsLength(); +1562 // Save an object allocation where we can +1563 if (tagsLength == 0) { +1564 return TagUtil.EMPTY_TAGS_ITR; 1565 } -1566 -1567 @Override -1568 public void remove() { -1569 throw new UnsupportedOperationException(); -1570 } -1571 }; +1566 if (cell instanceof ByteBufferCell) { +1567 return tagsIterator(((ByteBufferCell) cell).getTagsByteBuffer(), +1568 ((ByteBufferCell) cell).getTagsPosition(), tagsLength); +1569 } +1570 return tagsIterator(cell.getTagsArray(), cell.getTagsOffset(), tagsLength); +1571 } 1572 1573 /** -1574 * Util method to iterate through the tags in the given cell. -1575 * -1576 * @param cell The Cell over which tags iterator is needed. -1577 * @return iterator for the tags -1578 */ -1579 public static Iterator<Tag> tagsIterator(final Cell cell) { -1580 final int tagsLength = cell.getTagsLength(); -1581 // Save an object allocation where we can -1582 if (tagsLength == 0) { -1583 return TagUtil.EMPTY_TAGS_ITR; -1584 } -1585 if (cell instanceof ByteBufferCell) { -1586 return tagsIterator(((ByteBufferCell) cell).getTagsByteBuffer(), -1587 ((ByteBufferCell) cell).getTagsPosition(), tagsLength); -1588 } -1589 return tagsIterator(cell.getTagsArray(), cell.getTagsOffset(), tagsLength); -1590 } -1591 -1592 /** -1593 * @param cell The Cell -1594 * @return Tags in the given Cell as a List -1595 */ -1596 public static List<Tag> getTags(Cell cell) { -1597 List<Tag> tags = new ArrayList<>(); -1598 Iterator<Tag> tagsItr = tagsIterator(cell); -1599 while (tagsItr.hasNext()) { -1600 tags.add(tagsItr.next()); -1601 } -1602 return tags; -1603 } -1604 -1605 /** -1606 * Retrieve Cell's first tag, matching the passed in type -1607 * -1608 * @param cell The Cell -1609 * @param type Type of the Tag to retrieve -1610 * @return null if there is no tag of the passed in tag type -1611 */ -1612 public static Tag getTag(Cell cell, byte type){ -1613 boolean bufferBacked = cell instanceof ByteBufferCell; -1614 int length = cell.getTagsLength(); -1615 int offset = bufferBacked? ((ByteBufferCell)cell).getTagsPosition():cell.getTagsOffset(); -1616 int pos = offset; -1617 while (pos < offset + length) { -1618 int tagLen; -1619 if (bufferBacked) { -1620 ByteBuffer tagsBuffer = ((ByteBufferCell)cell).getTagsByteBuffer(); -1621 tagLen = ByteBufferUtils.readAsInt(tagsBuffer, pos, TAG_LENGTH_SIZE); -1622 if (ByteBufferUtils.toByte(tagsBuffer, pos + TAG_LENGTH_SIZE) == type) { -1623 return new ByteBufferTag(tagsBuffer, pos, tagLen + TAG_LENGTH_SIZE); -1624 } -1625 } else { -1626 tagLen = Bytes.readAsInt(cell.getTagsArray(), pos, TAG_LENGTH_SIZE); -1627 if (cell.getTagsArray()[pos + TAG_LENGTH_SIZE] == type) { -1628 return new ArrayBackedTag(cell.getTagsArray(), pos, tagLen + TAG_LENGTH_SIZE); -1629 } -1630 } -1631 pos += TAG_LENGTH_SIZE + tagLen; -1632 } -1633 return null; -1634 } -1635 -1636 /** -1637 * Returns true if the first range start1...end1 overlaps with the second range -1638 * start2...end2, assuming the byte arrays represent row keys -1639 */ -1640 public static boolean overlappingKeys(final byte[] start1, final byte[] end1, -1641 final byte[] start2, final byte[] end2) { -1642 return (end2.length == 0 || start1.length == 0 || Bytes.compareTo(start1, -1643 end2) < 0) -1644 && (end1.length == 0 || start2.length == 0 || Bytes.compareTo(start2, -1645 end1) < 0); -1646 } -1647 -1648 /** -1649 * Sets the given seqId to the cell. -1650 * Marked as audience Private as of 1.2.0. -1651 * Setting a Cell sequenceid is an internal implementation detail not for general public use. -1652 * @param cell -1653 * @param seqId -1654 * @throws IOException when the passed cell is not of type {@link SettableSequenceId} -1655 */ -1656 @InterfaceAudience.Private -1657 public static void setSequenceId(Cell cell, long seqId) throws IOException { -1658 if (cell instanceof SettableSequenceId) { -1659 ((SettableSequenceId) cell).setSequenceId(seqId); -1660 } else { -1661 throw new IOException(new UnsupportedOperationException("Cell is not of type " -1662 + SettableSequenceId.class.getName())); -1663 } -1664 } -1665 -1666 /** -1667 * Sets the given timestamp to the cell. -1668 * @param cell -1669 * @param ts -1670 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} -1671 */ -1672 public static void setTimestamp(Cell cell, long ts) throws IOException { -1673 if (cell instanceof SettableTimestamp) { -1674 ((SettableTimestamp) cell).setTimestamp(ts); -1675 } else { -1676 throw new IOException(new UnsupportedOperationException("Cell is not of type " -1677 + SettableTimestamp.class.getName())); -1678 } -1679 } -1680 -1681 /** -1682 * Sets the given timestamp to the cell. -1683 * @param cell -1684 * @param ts buffer containing the timestamp value -1685 * @param tsOffset offset to the new timestamp -1686 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} -1687 */ -1688 public static void setTimestamp(Cell cell, byte[] ts, int tsOffset) throws IOException { -1689 if (cell instanceof SettableTimestamp) { -1690 ((SettableTimestamp) cell).setTimestamp(ts, tsOffset); -1691 } else { -1692 throw new IOException(new UnsupportedOperationException("Cell is not of type " -1693 + SettableTimestamp.class.getName())); -1694 } -1695 } -1696 -1697 /** -1698 * Sets the given timestamp to the cell iff current timestamp is -1699 * {@link HConstants#LATEST_TIMESTAMP}. -1700 * @param cell -1701 * @param ts -1702 * @return True if cell timestamp is modified. -1703 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} -1704 */ -1705 public static boolean updateLatestStamp(Cell cell, long ts) throws IOException { -1706 if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP) { -1707 setTimestamp(cell, ts); -1708 return true; -1709 } -1710 return false; -1711 } -1712 -1713 /** -1714 * Sets the given timestamp to the cell iff current timestamp is -1715 * {@link HConstants#LATEST_TIMESTAMP}. -1716 * @param cell -1717 * @param ts buffer containing the timestamp value -1718 * @param tsOffset offset to the new timestamp -1719 * @return True if cell timestamp is modified. -1720 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} -1721 */ -1722 public static boolean updateLatestStamp(Cell cell, byte[] ts, int tsOffset) throws IOException { -1723 if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP) { -1724 setTimestamp(cell, ts, tsOffset); -1725 return true; -1726 } -1727 return false; -1728 } -1729 -1730 /** -1731 * Writes the Cell's key part as it would have serialized in a KeyValue. The format is &lt;2 bytes -1732 * rk len&gt;&lt;rk&gt;&lt;1 byte cf len&gt;&lt;cf&gt;&lt;qualifier&gt;&lt;8 bytes -1733 * timestamp&gt;&lt;1 byte type&gt; -1734 * @param cell -1735 * @param out -1736 * @throws IOException -1737 */ -1738 public static void writeFlatKey(Cell cell, DataOutputStream out) throws IOException { -1739 short rowLen = cell.getRowLength(); -1740 byte fLen = cell.getFamilyLength(); -1741 int qLen = cell.getQualifierLength(); -1742 // Using just one if/else loop instead of every time checking before writing every -1743 // component of cell -1744 if (cell instanceof ByteBufferCell) { -1745 out.writeShort(rowLen); -1746 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), -1747 ((ByteBufferCell) cell).getRowPosition(), rowLen); -1748 out.writeByte(fLen); -1749 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(), -1750 ((ByteBufferCell) cell).getFamilyPosition(), fLen); -1751 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), -1752 ((ByteBufferCell) cell).getQualifierPosition(), qLen); -1753 } else { -1754 out.writeShort(rowLen); -1755 out.write(cell.getRowArray(), cell.getRowOffset(), rowLen); -1756 out.writeByte(fLen); -1757 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), fLen); -1758 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qLen); -1759 } -1760 out.writeLong(cell.getTimestamp()); -1761 out.writeByte(cell.getTypeByte()); -1762 } -1763 -1764 public static int writeFlatKey(Cell cell, OutputStream out) throws IOException { -1765 short rowLen = cell.getRowLength(); -1766 byte fLen = cell.getFamilyLength(); -1767 int qLen = cell.getQualifierLength(); -1768 // Using just one if/else loop instead of every time checking before writing every -1769 // component of cell -1770 if (cell instanceof ByteBufferCell) { -1771 StreamUtils.writeShort(out, rowLen); -1772 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), -1773 ((ByteBufferCell) cell).getRowPosition(), rowLen); -1774 out.write(fLen); -1775 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(), -1776 ((ByteBufferCell) cell).getFamilyPosition(), fLen); -1777 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), -1778 ((ByteBufferCell) cell).getQualifierPosition(), qLen); -1779 } else { -1780 StreamUtils.writeShort(out, rowLen); -1781 out.write(cell.getRowArray(), cell.getRowOffset(), rowLen); -1782 out.write(fLen); -1783 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), fLen); -1784 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qLen); -1785 } -1786 StreamUtils.writeLong(out, cell.getTimestamp()); -1787 out.write(cell.getTypeByte()); -1788 return Bytes.SIZEOF_SHORT + rowLen + Bytes.SIZEOF_BYTE + fLen + qLen + Bytes.SIZEOF_LONG -1789 + Bytes.SIZEOF_BYTE; -1790 } -1791 -1792 /** -1793 * Writes the row from the given cell to the output stream -1794 * @param out The outputstream to which the data has to be written -1795 * @param cell The cell whose contents has to be written -1796 * @param rlength the row length -1797 * @throws IOException -1798 */ -1799 public static void writeRow(OutputStream out, Cell cell, short rlength) throws IOException { -1800 if (cell instanceof ByteBufferCell) { -1801 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), -1802 ((ByteBufferCell) cell).getRowPosition(), rlength); -1803 } else { -1804 out.write(cell.getRowArray(), cell.getRowOffset(), rlength); -1805 } -1806 } -1807 -1808 /** -1809 * Writes the row from the given cell to the output stream excluding the common prefix -1810 * @param out The dataoutputstream to which the data has to be written -1811 * @param cell The cell whose contents has to be written -1812 * @param rlength the row length -1813 * @throws IOException -1814 */ -1815 public static void writeRowSkippingBytes(DataOutputStream out, Cell cell, short rlength, -1816 int commonPrefix) throws IOException { -1817 if (cell instanceof ByteBufferCell) { -1818 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), -1819 ((ByteBufferCell) cell).getRowPosition() + commonPrefix, rlength - commonPrefix); -1820 } else { -1821 out.write(cell.getRowArray(), cell.getRowOffset() + commonPrefix, rlength - commonPrefix); -1822 } -1823 } -1824 -1825 /** -1826 * Writes the family from the given cell to the output stream -1827 * @param out The outputstream to which the data has to be written -1828 * @param cell The cell whose contents has to be written -1829 * @param flength the family length -1830 * @throws IOException -1831 */ -1832 public static void writeFamily(OutputStream out, Cell cell, byte flength) throws IOException { -1833 if (cell instanceof ByteBufferCell) { -1834 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(), -1835 ((ByteBufferCell) cell).getFamilyPosition(), flength); -1836 } else { -1837 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), flength); -1838 } -1839 } -1840 -1841 /** -1842 * Writes the qualifier from the given cell to the output stream -1843 * @param out The outputstream to which the data has to be written -1844 * @param cell The cell whose contents has to be written -1845 * @param qlength the qualifier length -1846 * @throws IOException -1847 */ -1848 public static void writeQualifier(OutputStream out, Cell cell, int qlength) -1849 throws IOException { -1850 if (cell instanceof ByteBufferCell) { -1851 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), -1852 ((ByteBufferCell) cell).getQualifierPosition(), qlength); -1853 } else { -1854 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qlength); -1855 } -1856 } -1857 -1858 /** -1859 * Writes the qualifier from the given cell to the output stream excluding the common prefix -1860 * @param out The dataoutputstream to which the data has to be written -1861 * @param cell The cell whose contents has to be written -1862 * @param qlength the qualifier length -1863 * @throws IOException -1864 */ -1865 public static void writeQualifierSkippingBytes(DataOutputStream out, Cell cell, -1866 int qlength, int commonPrefix) throws IOException { -1867 if (cell instanceof ByteBufferCell) { -1868 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), -1869 ((ByteBufferCell) cell).getQualifierPosition() + commonPrefix, qlength - commonPrefix); -1870 } else { -1871 out.write(cell.getQualifierArray(), cell.getQualifierOffset() + commonPrefix, -1872 qlength - commonPrefix); -1873 } -1874 } -1875 -1876 /** -1877 * Writes the value from the given cell to the output stream -1878 * @param out The outputstream to which the data has to be written -1879 * @param cell The cell whose contents has to be written -1880 * @param vlength the value length -1881 * @throws IOException -1882 */ -1883 public static void writeValue(OutputStream out, Cell cell, int vlength) throws IOException { -1884 if (cell instanceof ByteBufferCell) { -1885 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getValueByteBuffer(), -1886 ((ByteBufferCell) cell).getValuePosition(), vlength); -1887 } else { -1888 out.write(cell.getValueArray(), cell.getValueOffset(), vlength); -1889 } -1890 } -1891 -1892 /** -1893 * Writes the tag from the given cell to the output stream -1894 * @param out The outputstream to which the data has to be written -1895 * @param cell The cell whose contents has to be written -1896 * @param tagsLength the tag length -1897 * @throws IOException -1898 */ -1899 public static void writeTags(OutputStream out, Cell cell, int tagsLength) throws IOException { -1900 if (cell instanceof ByteBufferCell) { -1901 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getTagsByteBuffer(), -1902 ((ByteBufferCell) cell).getTagsPosition(), tagsLength); -1903 } else { -1904 out.write(cell.getTagsArray(), cell.getTagsOffset(), tagsLength); -1905 } -1906 } -1907 -1908 /** -1909 * @param cell -1910 * @return The Key portion of the passed <code>cell</code> as a String. -1911 */ -1912 public static String getCellKeyAsString(Cell cell) { -1913 StringBuilder sb = new StringBuilder(Bytes.toStringBinary( -1914 cell.getRowArray(), cell.getRowOffset(), cell.getRowLength())); -1915 sb.append('/'); -1916 sb.append(cell.getFamilyLength() == 0? "": -1917 Bytes.toStringBinary(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength())); -1918 // KeyValue only added ':' if family is non-null. Do same. -1919 if (cell.getFamilyLength() > 0) sb.append(':'); -1920 sb.append(cell.getQualifierLength() == 0? "": -1921 Bytes.toStringBinary(cell.getQualifierArray(), cell.getQualifierOffset(), -1922 cell.getQualifierLength())); -1923 sb.append('/'); -1924 sb.append(KeyValue.humanReadableTimestamp(cell.getTimestamp())); -1925 sb.append('/'); -1926 sb.append(Type.codeToType(cell.getTypeByte())); -1927 if (!(cell instanceof KeyValue.KeyOnlyKeyValue)) { -1928 sb.append("/vlen="); -1929 sb.append(cell.getValueLength()); -1930 } -1931 sb.append("/seqid="); -1932 sb.append(cell.getSequenceId()); -1933 return sb.toString(); -1934 } -1935 -1936 /** -1937 * This method exists just to encapsulate how we serialize keys. To be replaced by a factory -1938 * that we query to figure what the Cell implementation is and then, what serialization engine -1939 * to use and further, how to serialize the key for inclusion in hfile index. TODO. -1940 * @param cell -1941 * @return The key portion of the Cell serialized in the old-school KeyValue way or null if -1942 * passed a null <code>cell</code> -1943 */ -1944 public static byte [] getCellKeySerializedAsKeyValueKey(final Cell cell) { -1945 if (cell == null) return null; -1946 byte [] b = new byte[KeyValueUtil.keyLength(cell)]; -1947 KeyValueUtil.appendKeyTo(cell, b, 0); -1948 return b; -1949 } -1950 -1951 /** -1952 * Write rowkey excluding the common part. -1953 * @param cell -1954 * @param rLen -1955 * @param commonPrefix -1956 * @param out -1957 * @throws IOException -1958 */ -1959 public static void writeRowKeyExcludingCommon(Cell cell, short rLen, int commonPrefix, -1960 DataOutputStream out) throws IOException { -1961 if (commonPrefix == 0) { -1962 out.writeShort(rLen); -1963 } else if (commonPrefix == 1) { -1964 out.writeByte((byte) rLen); -1965 commonPrefix--; -1966 } else { -1967 commonPrefix -= KeyValue.ROW_LENGTH_SIZE; -1968 } -1969 if (rLen > commonPrefix) { -1970 writeRowSkippingBytes(out, cell, rLen, commonPrefix); -1971 } -1972 } -1973 -1974 /** -1975 * Find length of common prefix in keys of the cells, considering key as byte[] if serialized in -1976 * {@link KeyValue}. The key format is &lt;2 bytes rk len&gt;&lt;rk&gt;&lt;1 byte cf -1977 * len&gt;&lt;cf&gt;&lt;qualifier&gt;&lt;8 bytes timestamp&gt;&lt;1 byte type&gt; -1978 * @param c1 -1979 * the cell -1980 * @param c2 -1981 * the cell -1982 * @param bypassFamilyCheck -1983 * when true assume the family bytes same in both cells. Pass it as true when dealing -1984 * with Cells in same CF so as to avoid some checks -1985 * @param withTsType -1986 * when true check timestamp and type bytes also. -1987 * @return length of common prefix -1988 */ -1989 public static int findCommonPrefixInFlatKey(Cell c1, Cell c2, boolean bypassFamilyCheck, -1990 boolean withTsType) { -1991 // Compare the 2 bytes in RK length part -1992 short rLen1 = c1.getRowLength(); -1993 short rLen2 = c2.getRowLength(); -1994 int commonPrefix = KeyValue.ROW_LENGTH_SIZE; -1995 if (rLen1 != rLen2) { -1996 // early out when the RK length itself is not matching -1997 return ByteBufferUtils.findCommonPrefix(Bytes.toBytes(rLen1), 0, KeyValue.ROW_LENGTH_SIZE, -1998 Bytes.toBytes(rLen2), 0, KeyValue.ROW_LENGTH_SIZE); -1999 } -2000 // Compare the RKs -2001 int rkCommonPrefix = 0; -2002 if (c1 instanceof ByteBufferCell && c2 instanceof ByteBufferCell) { -2003 rkCommonPrefix = ByteBufferUtils.findCommonPrefix(((ByteBufferCell) c1).getRowByteBuffer(), -2004 ((ByteBufferCell) c1).getRowPosition(), rLen1, ((ByteBufferCell) c2).getRowByteBuffer(), -2005 ((ByteBufferCell) c2).getRowPosition(), rLen2); -2006 } else { -2007 // There cannot be a case where one cell is BBCell and other is KeyValue. This flow comes either -2008 // in flush or compactions. In flushes both cells are KV and in case of compaction it will be either -2009 // KV or BBCell -2010 rkCommonPrefix = ByteBufferUtils.findCommonPrefix(c1.getRowArray(), c1.getRowOffset(), -2011 rLen1, c2.getRowArray(), c2.getRowOffset(), rLen2); -2012 } -2013 commonPrefix += rkCommonPrefix; -2014 if (rkCommonPrefix != rLen1) { -2015 // Early out when RK is not fully matching. -2016 return commonPrefix; -2017 } -2018 // Compare 1 byte CF length part -2019 byte fLen1 = c1.getFamilyLength(); -2020 if (bypassFamilyCheck) { -2021 // This flag will be true when caller is sure that the family will be same for both the cells -2022 // Just make commonPrefix to increment by the family part -2023 commonPrefix += KeyValue.FAMILY_LENGTH_SIZE + fLen1; -2024 } else { -2025 byte fLen2 = c2.getFamilyLength(); -2026 if (fLen1 != fLen2) { -2027 // early out when the CF length itself is not matching -2028 return commonPrefix; -2029 } -2030 // CF lengths are same so there is one more byte common in key part -2031 commonPrefix += KeyValue.FAMILY_LENGTH_SIZE; -2032 // Compare the CF names -2033 int fCommonPrefix; -2034 if (c1 instanceof ByteBufferCell && c2 instanceof ByteBufferCell) { -2035 fCommonPrefix = -2036 ByteBufferUtils.findCommonPrefix(((ByteBufferCell) c1).getFamilyByteBuffer(), -2037 ((ByteBufferCell) c1).getFamilyPosition(), fLen1, -2038 ((ByteBufferCell) c2).getFamilyByteBuffer(), -2039 ((ByteBufferCell) c2).getFamilyPosition(), fLen2); -2040 } else { -2041 fCommonPrefix = ByteBufferUtils.findCommonPrefix(c1.getFamilyArray(), c1.getFamilyOffset(), -2042 fLen1, c2.getFamilyArray(), c2.getFamilyOffset(), fLen2); -2043 } -2044 commonPrefix += fCommonPrefix; -2045 if (fCommonPrefix != fLen1) { -2046 return commonPrefix; -2047 } -2048 } -2049 // Compare the Qualifiers -2050 int qLen1 = c1.getQualifierLength(); -2051 int qLen2 = c2.getQualifierLength(); -2052 int qCommon; -2053 if (c1 instanceof ByteBufferCell && c2 instanceof ByteBufferCell) { -2054 qCommon = ByteBufferUtils.findCommonPrefix(((ByteBufferCell) c1).getQualifierByteBuffer(), -2055 ((ByteBufferCell) c1).getQualifierPosition(), qLen1, -2056 ((ByteBufferCell) c2).getQualifierByteBuffer(), -2057 ((ByteBufferCell) c2).getQualifierPosition(), qLen2); -2058 } else { -2059 qCommon = ByteBufferUtils.findCommonPrefix(c1.getQualifierArray(), c1.getQualifierOffset(), -2060 qLen1, c2.getQualifierArray(), c2.getQualifierOffset(), qLen2); -2061 } -2062 commonPrefix += qCommon; -2063 if (!withTsType || Math.max(qLen1, qLen2) != qCommon) { -2064 return commonPrefix; +1574 * @param cell The Cell +1575 * @return Tags in the given Cell as a List +1576 */ +1577 public static List<Tag> getTags(Cell cell) { +1578 List<Tag> tags = new ArrayList<>(); +1579 Iterator<Tag> tagsItr = tagsIterator(cell); +1580 while (tagsItr.hasNext()) { +1581 tags.add(tagsItr.next()); +1582 } +1583 return tags; +1584 } +1585 +1586 /** +1587 * Retrieve Cell's first tag, matching the passed in type +1588 * +1589 * @param cell The Cell +1590 * @param type Type of the Tag to retrieve +1591 * @return null if there is no tag of the passed in tag type +1592 */ +1593 public static Tag getTag(Cell cell, byte type){ +1594 boolean bufferBacked = cell instanceof ByteBufferCell; +1595 int length = cell.getTagsLength(); +1596 int offset = bufferBacked? ((ByteBufferCell)cell).getTagsPosition():cell.getTagsOffset(); +1597 int pos = offset; +1598 while (pos < offset + length) { +1599 int tagLen; +1600 if (bufferBacked) { +1601 ByteBuffer tagsBuffer = ((ByteBufferCell)cell).getTagsByteBuffer(); +1602 tagLen = ByteBufferUtils.readAsInt(tagsBuffer, pos, TAG_LENGTH_SIZE); +1603 if (ByteBufferUtils.toByte(tagsBuffer, pos + TAG_LENGTH_SIZE) == type) { +1604 return new ByteBufferTag(tagsBuffer, pos, tagLen + TAG_LENGTH_SIZE); +1605 } +1606 } else { +1607 tagLen = Bytes.readAsInt(cell.getTagsArray(), pos, TAG_LENGTH_SIZE); +1608 if (cell.getTagsArray()[pos + TAG_LENGTH_SIZE] == type) { +1609 return new ArrayBackedTag(cell.getTagsArray(), pos, tagLen + TAG_LENGTH_SIZE); +1610 } +1611 } +1612 pos += TAG_LENGTH_SIZE + tagLen; +1613 } +1614 return null; +1615 } +1616 +1617 /** +1618 * Returns true if the first range start1...end1 overlaps with the second range +1619 * start2...end2, assuming the byte arrays represent row keys +1620 */ +1621 public static boolean overlappingKeys(final byte[] start1, final byte[] end1, +1622 final byte[] start2, final byte[] end2) { +1623 return (end2.length == 0 || start1.length == 0 || Bytes.compareTo(start1, +1624 end2) < 0) +1625 && (end1.length == 0 || start2.length == 0 || Bytes.compareTo(start2, +1626 end1) < 0); +1627 } +1628 +1629 /** +1630 * Sets the given seqId to the cell. +1631 * Marked as audience Private as of 1.2.0. +1632 * Setting a Cell sequenceid is an internal implementation detail not for general public use. +1633 * @param cell +1634 * @param seqId +1635 * @throws IOException when the passed cell is not of type {@link SettableSequenceId} +1636 */ +1637 @InterfaceAudience.Private +1638 public static void setSequenceId(Cell cell, long seqId) throws IOException { +1639 if (cell instanceof SettableSequenceId) { +1640 ((SettableSequenceId) cell).setSequenceId(seqId); +1641 } else { +1642 throw new IOException(new UnsupportedOperationException("Cell is not of type " +1643 + SettableSequenceId.class.getName())); +1644 } +1645 } +1646 +1647 /** +1648 * Sets the given timestamp to the cell. +1649 * @param cell +1650 * @param ts +1651 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} +1652 */ +1653 public static void setTimestamp(Cell cell, long ts) throws IOException { +1654 if (cell instanceof SettableTimestamp) { +1655 ((SettableTimestamp) cell).setTimestamp(ts); +1656 } else { +1657 throw new IOException(new UnsupportedOperationException("Cell is not of type " +1658 + SettableTimestamp.class.getName())); +1659 } +1660 } +1661 +1662 /** +1663 * Sets the given timestamp to the cell. +1664 * @param cell +1665 * @param ts buffer containing the timestamp value +1666 * @param tsOffset offset to the new timestamp +1667 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} +1668 */ +1669 public static void setTimestamp(Cell cell, byte[] ts, int tsOffset) throws IOException { +1670 if (cell instanceof SettableTimestamp) { +1671 ((SettableTimestamp) cell).setTimestamp(ts, tsOffset); +1672 } else { +1673 throw new IOException(new UnsupportedOperationException("Cell is not of type " +1674 + SettableTimestamp.class.getName())); +1675 } +1676 } +1677 +1678 /** +1679 * Sets the given timestamp to the cell iff current timestamp is +1680 * {@link HConstants#LATEST_TIMESTAMP}. +1681 * @param cell +1682 * @param ts +1683 * @return True if cell timestamp is modified. +1684 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} +1685 */ +1686 public static boolean updateLatestStamp(Cell cell, long ts) throws IOException { +1687 if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP) { +1688 setTimestamp(cell, ts); +1689 return true; +1690 } +1691 return false; +1692 } +1693 +1694 /** +1695 * Sets the given timestamp to the cell iff current timestamp is +1696 * {@link HConstants#LATEST_TIMESTAMP}. +1697 * @param cell +1698 * @param ts buffer containing the timestamp value +1699 * @param tsOffset offset to the new timestamp +1700 * @return True if cell timestamp is modified. +1701 * @throws IOException when the passed cell is not of type {@link SettableTimestamp} +1702 */ +1703 public static boolean updateLatestStamp(Cell cell, byte[] ts, int tsOffset) throws IOException { +1704 if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP) { +1705 setTimestamp(cell, ts, tsOffset); +1706 return true; +1707 } +1708 return false; +1709 } +1710 +1711 /** +1712 * Writes the Cell's key part as it would have serialized in a KeyValue. The format is &lt;2 bytes +1713 * rk len&gt;&lt;rk&gt;&lt;1 byte cf len&gt;&lt;cf&gt;&lt;qualifier&gt;&lt;8 bytes +1714 * timestamp&gt;&lt;1 byte type&gt; +1715 * @param cell +1716 * @param out +1717 * @throws IOException +1718 */ +1719 public static void writeFlatKey(Cell cell, DataOutputStream out) throws IOException { +1720 short rowLen = cell.getRowLength(); +1721 byte fLen = cell.getFamilyLength(); +1722 int qLen = cell.getQualifierLength(); +1723 // Using just one if/else loop instead of every time checking before writing every +1724 // component of cell +1725 if (cell instanceof ByteBufferCell) { +1726 out.writeShort(rowLen); +1727 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), +1728 ((ByteBufferCell) cell).getRowPosition(), rowLen); +1729 out.writeByte(fLen); +1730 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(), +1731 ((ByteBufferCell) cell).getFamilyPosition(), fLen); +1732 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), +1733 ((ByteBufferCell) cell).getQualifierPosition(), qLen); +1734 } else { +1735 out.writeShort(rowLen); +1736 out.write(cell.getRowArray(), cell.getRowOffset(), rowLen); +1737 out.writeByte(fLen); +1738 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), fLen); +1739 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qLen); +1740 } +1741 out.writeLong(cell.getTimestamp()); +1742 out.writeByte(cell.getTypeByte()); +1743 } +1744 +1745 public static int writeFlatKey(Cell cell, OutputStream out) throws IOException { +1746 short rowLen = cell.getRowLength(); +1747 byte fLen = cell.getFamilyLength(); +1748 int qLen = cell.getQualifierLength(); +1749 // Using just one if/else loop instead of every time checking before writing every +1750 // component of cell +1751 if (cell instanceof ByteBufferCell) { +1752 StreamUtils.writeShort(out, rowLen); +1753 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), +1754 ((ByteBufferCell) cell).getRowPosition(), rowLen); +1755 out.write(fLen); +1756 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(), +1757 ((ByteBufferCell) cell).getFamilyPosition(), fLen); +1758 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), +1759 ((ByteBufferCell) cell).getQualifierPosition(), qLen); +1760 } else { +1761 StreamUtils.writeShort(out, rowLen); +1762 out.write(cell.getRowArray(), cell.getRowOffset(), rowLen); +1763 out.write(fLen); +1764 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), fLen); +1765 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qLen); +1766 } +1767 StreamUtils.writeLong(out, cell.getTimestamp()); +1768 out.write(cell.getTypeByte()); +1769 return Bytes.SIZEOF_SHORT + rowLen + Bytes.SIZEOF_BYTE + fLen + qLen + Bytes.SIZEOF_LONG +1770 + Bytes.SIZEOF_BYTE; +1771 } +1772 +1773 /** +1774 * Writes the row from the given cell to the output stream +1775 * @param out The outputstream to which the data has to be written +1776 * @param cell The cell whose contents has to be written +1777 * @param rlength the row length +1778 * @throws IOException +1779 */ +1780 public static void writeRow(OutputStream out, Cell cell, short rlength) throws IOException { +1781 if (cell instanceof ByteBufferCell) { +1782 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), +1783 ((ByteBufferCell) cell).getRowPosition(), rlength); +1784 } else { +1785 out.write(cell.getRowArray(), cell.getRowOffset(), rlength); +1786 } +1787 } +1788 +1789 /** +1790 * Writes the row from the given cell to the output stream excluding the common prefix +1791 * @param out The dataoutputstream to which the data has to be written +1792 * @param cell The cell whose contents has to be written +1793 * @param rlength the row length +1794 * @throws IOException +1795 */ +1796 public static void writeRowSkippingBytes(DataOutputStream out, Cell cell, short rlength, +1797 int commonPrefix) throws IOException { +1798 if (cell instanceof ByteBufferCell) { +1799 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(), +1800 ((ByteBufferCell) cell).getRowPosition() + commonPrefix, rlength - commonPrefix); +1801 } else { +1802 out.write(cell.getRowArray(), cell.getRowOffset() + commonPrefix, rlength - commonPrefix); +1803 } +1804 } +1805 +1806 /** +1807 * Writes the family from the given cell to the output stream +1808 * @param out The outputstream to which the data has to be written +1809 * @param cell The cell whose contents has to be written +1810 * @param flength the family length +1811 * @throws IOException +1812 */ +1813 public static void writeFamily(OutputStream out, Cell cell, byte flength) throws IOException { +1814 if (cell instanceof ByteBufferCell) { +1815 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(), +1816 ((ByteBufferCell) cell).getFamilyPosition(), flength); +1817 } else { +1818 out.write(cell.getFamilyArray(), cell.getFamilyOffset(), flength); +1819 } +1820 } +1821 +1822 /** +1823 * Writes the qualifier from the given cell to the output stream +1824 * @param out The outputstream to which the data has to be written +1825 * @param cell The cell whose contents has to be written +1826 * @param qlength the qualifier length +1827 * @throws IOException +1828 */ +1829 public static void writeQualifier(OutputStream out, Cell cell, int qlength) +1830 throws IOException { +1831 if (cell instanceof ByteBufferCell) { +1832 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), +1833 ((ByteBufferCell) cell).getQualifierPosition(), qlength); +1834 } else { +1835 out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qlength); +1836 } +1837 } +1838 +1839 /** +1840 * Writes the qualifier from the given cell to the output stream excluding the common prefix +1841 * @param out The dataoutputstream to which the data has to be written +1842 * @param cell The cell whose contents has to be written +1843 * @param qlength the qualifier length +1844 * @throws IOException +1845 */ +1846 public static void writeQualifierSkippingBytes(DataOutputStream out, Cell cell, +1847 int qlength, int commonPrefix) throws IOException { +1848 if (cell instanceof ByteBufferCell) { +1849 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(), +1850 ((ByteBufferCell) cell).getQualifierPosition() + commonPrefix, qlength - commonPrefix); +1851 } else { +1852 out.write(cell.getQualifierArray(), cell.getQualifierOffset() + commonPrefix, +1853 qlength - commonPrefix); +1854 } +1855 } +1856 +1857 /** +1858 * Writes the value from the given cell to the output stream +1859 * @param out The outputstream to which the data has to be written +1860 * @param cell The cell whose contents has to be written +1861 * @param vlength the value length +1862 * @throws IOException +1863 */ +1864 public static void writeValue(OutputStream out, Cell cell, int vlength) throws IOException { +1865 if (cell instanceof ByteBufferCell) { +1866 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getValueByteBuffer(), +1867 ((ByteBufferCell) cell).getValuePosition(), vlength); +1868 } else { +1869 out.write(cell.getValueArray(), cell.getValueOffset(), vlength); +1870 } +1871 } +1872 +1873 /** +1874 * Writes the tag from the given cell to the output stream +1875 * @param out The outputstream to which the data has to be written +1876 * @param cell The cell whose contents has to be written +1877 * @param tagsLength the tag length +1878 * @throws IOException +1879 */ +1880 public static void writeTags(OutputStream out, Cell cell, int tagsLength) throws IOException { +1881 if (cell instanceof ByteBufferCell) { +1882 ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getTagsByteBuffer(), +1883 ((ByteBufferCell) cell).getTagsPosition(), tagsLength); +1884 } else { +1885 out.write(cell.getTagsArray(), cell.getTagsOffset(), tagsLength); +1886 } +1887 } +1888 +1889 /** +1890 * @param cell +1891 * @return The Key portion of the passed <code>cell</code> as a String. +1892 */ +1893 public static String getCellKeyAsString(Cell cell) { +1894 StringBuilder sb = new StringBuilder(Bytes.toStringBinary( +1895 cell.getRowArray(), cell.getRowOffset(), cell.getRowLength())); +1896 sb.append('/'); +1897 sb.append(cell.getFamilyLength() == 0? "": +1898 Bytes.toStringBinary(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength())); +1899 // KeyValue only added ':' if fam