001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase;
019
020import java.util.Iterator;
021import java.util.List;
022import java.util.Optional;
023import org.apache.yetus.audience.InterfaceAudience;
024
025/**
026 * An extended version of Cell that allows CPs manipulate Tags.
027 */
028// Added by HBASE-19092 to expose Tags to CPs (history server) w/o exposing ExtendedCell.
029// Why is this in hbase-common and not in hbase-server where it is used?
030// RawCell is an odd name for a class that is only for CPs that want to manipulate Tags on
031// server-side only w/o exposing ExtendedCell -- super rare, super exotic.
032@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
033public interface RawCell extends Cell {
034  static final int MAX_TAGS_LENGTH = (2 * Short.MAX_VALUE) + 1;
035
036  /**
037   * Contiguous raw bytes representing tags that may start at any index in the containing array.
038   * @return the tags byte array
039   */
040  byte[] getTagsArray();
041
042  /**
043   * Return the first offset where the tags start in the Cell
044   */
045  int getTagsOffset();
046
047  /**
048   * HBase internally uses 2 bytes to store tags length in Cell. As the tags length is always a
049   * non-negative number, to make good use of the sign bit, the max of tags length is defined 2 *
050   * Short.MAX_VALUE + 1 = 65535. As a result, the return type is int, because a short is not
051   * capable of handling that. Please note that even if the return type is int, the max tags length
052   * is far less than Integer.MAX_VALUE.
053   * @return the total length of the tags in the Cell.
054   */
055  int getTagsLength();
056
057  /**
058   * Allows cloning the tags in the cell to a new byte[]
059   * @return the byte[] having the tags
060   */
061  default byte[] cloneTags() {
062    return PrivateCellUtil.cloneTags((ExtendedCell) this);
063  }
064
065  /**
066   * Creates a list of tags in the current cell
067   * @return a list of tags
068   */
069  default Iterator<Tag> getTags() {
070    return PrivateCellUtil.tagsIterator((ExtendedCell) this);
071  }
072
073  /**
074   * Returns the specific tag of the given type
075   * @param type the type of the tag
076   * @return the specific tag if available or null
077   */
078  default Optional<Tag> getTag(byte type) {
079    return PrivateCellUtil.getTag((ExtendedCell) this, type);
080  }
081
082  /**
083   * Check the length of tags. If it is invalid, throw IllegalArgumentException
084   * @param tagsLength the given length of tags
085   * @throws IllegalArgumentException if tagslength is invalid
086   */
087  public static void checkForTagsLength(int tagsLength) {
088    if (tagsLength > MAX_TAGS_LENGTH) {
089      throw new IllegalArgumentException("tagslength " + tagsLength + " > " + MAX_TAGS_LENGTH);
090    }
091  }
092
093  /** Returns A new cell which is having the extra tags also added to it. */
094  public static Cell createCell(Cell cell, List<Tag> tags) {
095    return PrivateCellUtil.createCell((ExtendedCell) cell, tags);
096  }
097}