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.nio.ByteBuffer; 021import org.apache.hadoop.hbase.util.ByteBufferUtils; 022import org.apache.hadoop.hbase.util.Bytes; 023import org.apache.yetus.audience.InterfaceAudience; 024import org.apache.yetus.audience.InterfaceStability; 025 026/** 027 * Tags are part of cells and helps to add metadata about them. Metadata could be ACLs, visibility 028 * labels, etc. 029 * <p> 030 * Each Tag is having a type (one byte) and value part. The max value length for a Tag is 65533. 031 * <p> 032 * See {@link TagType} for reserved tag types. 033 */ 034@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) 035@InterfaceStability.Evolving 036public interface Tag { 037 038 public final static int TYPE_LENGTH_SIZE = Bytes.SIZEOF_BYTE; 039 public final static int TAG_LENGTH_SIZE = Bytes.SIZEOF_SHORT; 040 public final static int INFRASTRUCTURE_SIZE = TYPE_LENGTH_SIZE + TAG_LENGTH_SIZE; 041 public static final int MAX_TAG_LENGTH = (2 * Short.MAX_VALUE) + 1 - TAG_LENGTH_SIZE; 042 043 /** 044 * Custom tags if created are suggested to be above this range. So that it does not overlap with 045 * internal tag types 046 */ 047 public static final byte CUSTOM_TAG_TYPE_RANGE = (byte) 64; 048 049 /** Returns the tag type */ 050 byte getType(); 051 052 /** Returns Offset of tag value within the backed buffer */ 053 int getValueOffset(); 054 055 /** Returns Length of tag value within the backed buffer */ 056 int getValueLength(); 057 058 /** Return true if the tag is backed by a byte array */ 059 boolean hasArray(); 060 061 /** 062 * Return an array containing the value bytes if {@link #hasArray()} returns true. 063 * <p> 064 * Use {@link #getValueByteBuffer()} otherwise. 065 */ 066 byte[] getValueArray(); 067 068 /** Returns The {@link java.nio.ByteBuffer} containing the value bytes. */ 069 ByteBuffer getValueByteBuffer(); 070 071 /** 072 * Returns tag value in a new byte array. Primarily for use client-side. If server-side, use 073 * {@link Tag#getValueArray()} with appropriate {@link Tag#getValueOffset()} and 074 * {@link Tag#getValueLength()} instead to save on allocations. 075 * @param tag The Tag whose value to be returned 076 * @return tag value in a new byte array. 077 */ 078 public static byte[] cloneValue(Tag tag) { 079 int tagLength = tag.getValueLength(); 080 byte[] tagArr = new byte[tagLength]; 081 if (tag.hasArray()) { 082 Bytes.putBytes(tagArr, 0, tag.getValueArray(), tag.getValueOffset(), tagLength); 083 } else { 084 ByteBufferUtils.copyFromBufferToArray(tagArr, tag.getValueByteBuffer(), tag.getValueOffset(), 085 0, tagLength); 086 } 087 return tagArr; 088 } 089 090 /** 091 * Converts the value bytes of the given tag into a String value 092 * @param tag The Tag 093 * @return value as String 094 */ 095 public static String getValueAsString(Tag tag) { 096 if (tag.hasArray()) { 097 return Bytes.toString(tag.getValueArray(), tag.getValueOffset(), tag.getValueLength()); 098 } 099 return Bytes.toString(cloneValue(tag)); 100 } 101 102 /** 103 * Matches the value part of given tags 104 * @param t1 Tag to match the value 105 * @param t2 Tag to match the value 106 * @return True if values of both tags are same. 107 */ 108 public static boolean matchingValue(Tag t1, Tag t2) { 109 if (t1.hasArray() && t2.hasArray()) { 110 return Bytes.equals(t1.getValueArray(), t1.getValueOffset(), t1.getValueLength(), 111 t2.getValueArray(), t2.getValueOffset(), t2.getValueLength()); 112 } 113 if (t1.hasArray()) { 114 return ByteBufferUtils.equals(t2.getValueByteBuffer(), t2.getValueOffset(), 115 t2.getValueLength(), t1.getValueArray(), t1.getValueOffset(), t1.getValueLength()); 116 } 117 if (t2.hasArray()) { 118 return ByteBufferUtils.equals(t1.getValueByteBuffer(), t1.getValueOffset(), 119 t1.getValueLength(), t2.getValueArray(), t2.getValueOffset(), t2.getValueLength()); 120 } 121 return ByteBufferUtils.equals(t1.getValueByteBuffer(), t1.getValueOffset(), t1.getValueLength(), 122 t2.getValueByteBuffer(), t2.getValueOffset(), t2.getValueLength()); 123 } 124 125 /** 126 * Copies the tag's value bytes to the given byte array 127 * @param tag The Tag 128 * @param out The byte array where to copy the Tag value. 129 * @param offset The offset within 'out' array where to copy the Tag value. 130 */ 131 public static void copyValueTo(Tag tag, byte[] out, int offset) { 132 if (tag.hasArray()) { 133 Bytes.putBytes(out, offset, tag.getValueArray(), tag.getValueOffset(), tag.getValueLength()); 134 } else { 135 ByteBufferUtils.copyFromBufferToArray(out, tag.getValueByteBuffer(), tag.getValueOffset(), 136 offset, tag.getValueLength()); 137 } 138 } 139 140 /** 141 * Converts the value bytes of the given tag into a long value 142 * @param tag The Tag 143 * @return value as long 144 */ 145 public static long getValueAsLong(Tag tag) { 146 if (tag.hasArray()) { 147 return Bytes.toLong(tag.getValueArray(), tag.getValueOffset(), tag.getValueLength()); 148 } 149 return ByteBufferUtils.toLong(tag.getValueByteBuffer(), tag.getValueOffset()); 150 } 151 152 /** 153 * Converts the value bytes of the given tag into a byte value 154 * @param tag The Tag 155 * @return value as byte 156 */ 157 public static byte getValueAsByte(Tag tag) { 158 if (tag.hasArray()) { 159 return tag.getValueArray()[tag.getValueOffset()]; 160 } 161 return ByteBufferUtils.toByte(tag.getValueByteBuffer(), tag.getValueOffset()); 162 } 163}