001/** 002 * Copyright The Apache Software Foundation 003 * 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020package org.apache.hadoop.hbase; 021 022import java.nio.ByteBuffer; 023 024import org.apache.hadoop.hbase.util.ByteBufferUtils; 025import org.apache.hadoop.hbase.util.Bytes; 026import org.apache.yetus.audience.InterfaceAudience; 027import org.apache.yetus.audience.InterfaceStability; 028 029/** 030 * Tags are part of cells and helps to add metadata about them. 031 * Metadata could be ACLs, visibility labels, etc. 032 * <p> 033 * Each Tag is having a type (one byte) and value part. The max value length for a Tag is 65533. 034 * <p> 035 * See {@link TagType} for reserved tag types. 036 */ 037@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) 038@InterfaceStability.Evolving 039public interface Tag { 040 041 public final static int TYPE_LENGTH_SIZE = Bytes.SIZEOF_BYTE; 042 public final static int TAG_LENGTH_SIZE = Bytes.SIZEOF_SHORT; 043 public final static int INFRASTRUCTURE_SIZE = TYPE_LENGTH_SIZE + TAG_LENGTH_SIZE; 044 public static final int MAX_TAG_LENGTH = (2 * Short.MAX_VALUE) + 1 - TAG_LENGTH_SIZE; 045 046 /** 047 * Custom tags if created are suggested to be above this range. So that 048 * it does not overlap with internal tag types 049 */ 050 public static final byte CUSTOM_TAG_TYPE_RANGE = (byte)64; 051 /** 052 * @return the tag type 053 */ 054 byte getType(); 055 056 /** 057 * @return Offset of tag value within the backed buffer 058 */ 059 int getValueOffset(); 060 061 /** 062 * @return Length of tag value within the backed buffer 063 */ 064 int getValueLength(); 065 066 /** 067 * Tells whether or not this Tag is backed by a byte array. 068 * @return true when this Tag is backed by byte array 069 */ 070 boolean hasArray(); 071 072 /** 073 * @return The array containing the value bytes. 074 * @throws UnsupportedOperationException 075 * when {@link #hasArray()} return false. Use {@link #getValueByteBuffer()} in such 076 * situation 077 */ 078 byte[] getValueArray(); 079 080 /** 081 * @return The {@link java.nio.ByteBuffer} containing the value bytes. 082 */ 083 ByteBuffer getValueByteBuffer(); 084 085 /** 086 * Returns tag value in a new byte array. Primarily for use client-side. If server-side, use 087 * {@link Tag#getValueArray()} with appropriate {@link Tag#getValueOffset()} and 088 * {@link Tag#getValueLength()} instead to save on allocations. 089 * @param tag The Tag whose value to be returned 090 * @return tag value in a new byte array. 091 */ 092 public static byte[] cloneValue(Tag tag) { 093 int tagLength = tag.getValueLength(); 094 byte[] tagArr = new byte[tagLength]; 095 if (tag.hasArray()) { 096 Bytes.putBytes(tagArr, 0, tag.getValueArray(), tag.getValueOffset(), tagLength); 097 } else { 098 ByteBufferUtils.copyFromBufferToArray(tagArr, tag.getValueByteBuffer(), tag.getValueOffset(), 099 0, tagLength); 100 } 101 return tagArr; 102 } 103 104 /** 105 * Converts the value bytes of the given tag into a String value 106 * @param tag The Tag 107 * @return value as String 108 */ 109 public static String getValueAsString(Tag tag) { 110 if (tag.hasArray()) { 111 return Bytes.toString(tag.getValueArray(), tag.getValueOffset(), tag.getValueLength()); 112 } 113 return Bytes.toString(cloneValue(tag)); 114 } 115 116 /** 117 * Matches the value part of given tags 118 * @param t1 Tag to match the value 119 * @param t2 Tag to match the value 120 * @return True if values of both tags are same. 121 */ 122 public static boolean matchingValue(Tag t1, Tag t2) { 123 if (t1.hasArray() && t2.hasArray()) { 124 return Bytes.equals(t1.getValueArray(), t1.getValueOffset(), t1.getValueLength(), 125 t2.getValueArray(), t2.getValueOffset(), t2.getValueLength()); 126 } 127 if (t1.hasArray()) { 128 return ByteBufferUtils.equals(t2.getValueByteBuffer(), t2.getValueOffset(), 129 t2.getValueLength(), t1.getValueArray(), t1.getValueOffset(), t1.getValueLength()); 130 } 131 if (t2.hasArray()) { 132 return ByteBufferUtils.equals(t1.getValueByteBuffer(), t1.getValueOffset(), 133 t1.getValueLength(), t2.getValueArray(), t2.getValueOffset(), t2.getValueLength()); 134 } 135 return ByteBufferUtils.equals(t1.getValueByteBuffer(), t1.getValueOffset(), t1.getValueLength(), 136 t2.getValueByteBuffer(), t2.getValueOffset(), t2.getValueLength()); 137 } 138 139 /** 140 * Copies the tag's value bytes to the given byte array 141 * @param tag The Tag 142 * @param out The byte array where to copy the Tag value. 143 * @param offset The offset within 'out' array where to copy the Tag value. 144 */ 145 public static void copyValueTo(Tag tag, byte[] out, int offset) { 146 if (tag.hasArray()) { 147 Bytes.putBytes(out, offset, tag.getValueArray(), tag.getValueOffset(), tag.getValueLength()); 148 } else { 149 ByteBufferUtils.copyFromBufferToArray(out, tag.getValueByteBuffer(), tag.getValueOffset(), 150 offset, tag.getValueLength()); 151 } 152 } 153 154 /** 155 * Converts the value bytes of the given tag into a long value 156 * @param tag The Tag 157 * @return value as long 158 */ 159 public static long getValueAsLong(Tag tag) { 160 if (tag.hasArray()) { 161 return Bytes.toLong(tag.getValueArray(), tag.getValueOffset(), tag.getValueLength()); 162 } 163 return ByteBufferUtils.toLong(tag.getValueByteBuffer(), tag.getValueOffset()); 164 } 165 166 /** 167 * Converts the value bytes of the given tag into a byte value 168 * @param tag The Tag 169 * @return value as byte 170 */ 171 public static byte getValueAsByte(Tag tag) { 172 if (tag.hasArray()) { 173 return tag.getValueArray()[tag.getValueOffset()]; 174 } 175 return ByteBufferUtils.toByte(tag.getValueByteBuffer(), tag.getValueOffset()); 176 } 177}