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 java.util.Collection; 022import java.util.List; 023import org.apache.commons.lang3.StringUtils; 024import org.apache.hadoop.hbase.util.Bytes; 025import org.apache.hadoop.hbase.util.Strings; 026import org.apache.yetus.audience.InterfaceAudience; 027 028import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 029import org.apache.hbase.thirdparty.org.apache.commons.collections4.IterableUtils; 030 031@InterfaceAudience.Private 032public class KeyValueTestUtil { 033 034 public static KeyValue create(String row, String family, String qualifier, long timestamp, 035 String value) { 036 return create(row, family, qualifier, timestamp, KeyValue.Type.Put, value); 037 } 038 039 public static KeyValue create(String row, String family, String qualifier, long timestamp, 040 KeyValue.Type type, String value) { 041 return new KeyValue(Bytes.toBytes(row), Bytes.toBytes(family), Bytes.toBytes(qualifier), 042 timestamp, type, Bytes.toBytes(value)); 043 } 044 045 public static ByteBuffer toByteBufferAndRewind(final Iterable<? extends KeyValue> kvs, 046 boolean includeMemstoreTS) { 047 int totalBytes = KeyValueUtil.totalLengthWithMvccVersion(kvs, includeMemstoreTS); 048 ByteBuffer bb = ByteBuffer.allocate(totalBytes); 049 for (KeyValue kv : IterableUtils.emptyIfNull(kvs)) { 050 KeyValueUtil.appendToByteBuffer(bb, kv, includeMemstoreTS); 051 } 052 bb.rewind(); 053 return bb; 054 } 055 056 /** 057 * Checks whether KeyValues from kvCollection2 are contained in kvCollection1. The comparison is 058 * made without distinguishing MVCC version of the KeyValues 059 * @return true if KeyValues from kvCollection2 are contained in kvCollection1 060 */ 061 public static boolean containsIgnoreMvccVersion(Collection<? extends Cell> kvCollection1, 062 Collection<? extends Cell> kvCollection2) { 063 for (Cell kv1 : kvCollection1) { 064 boolean found = false; 065 for (Cell kv2 : kvCollection2) { 066 if (PrivateCellUtil.equalsIgnoreMvccVersion((ExtendedCell) kv1, (ExtendedCell) kv2)) { 067 found = true; 068 } 069 } 070 if (!found) { 071 return false; 072 } 073 } 074 return true; 075 } 076 077 public static List<KeyValue> rewindThenToList(final ByteBuffer bb, 078 final boolean includesMemstoreTS, final boolean useTags) { 079 bb.rewind(); 080 List<KeyValue> kvs = Lists.newArrayList(); 081 KeyValue kv = null; 082 while (true) { 083 kv = KeyValueUtil.nextShallowCopy(bb, includesMemstoreTS, useTags); 084 if (kv == null) { 085 break; 086 } 087 kvs.add(kv); 088 } 089 return kvs; 090 } 091 092 /********************* toString ************************************/ 093 094 public static String toStringWithPadding(final Collection<? extends KeyValue> kvs, 095 final boolean includeMeta) { 096 int maxRowStringLength = 0; 097 int maxFamilyStringLength = 0; 098 int maxQualifierStringLength = 0; 099 int maxTimestampLength = 0; 100 for (KeyValue kv : kvs) { 101 maxRowStringLength = Math.max(maxRowStringLength, getRowString(kv).length()); 102 maxFamilyStringLength = Math.max(maxFamilyStringLength, getFamilyString(kv).length()); 103 maxQualifierStringLength = 104 Math.max(maxQualifierStringLength, getQualifierString(kv).length()); 105 maxTimestampLength = 106 Math.max(maxTimestampLength, Long.valueOf(kv.getTimestamp()).toString().length()); 107 } 108 StringBuilder sb = new StringBuilder(); 109 for (KeyValue kv : kvs) { 110 if (sb.length() > 0) { 111 sb.append("\n"); 112 } 113 String row = toStringWithPadding(kv, maxRowStringLength, maxFamilyStringLength, 114 maxQualifierStringLength, maxTimestampLength, includeMeta); 115 sb.append(row); 116 } 117 return sb.toString(); 118 } 119 120 protected static String toStringWithPadding(final KeyValue kv, final int maxRowLength, 121 int maxFamilyLength, int maxQualifierLength, int maxTimestampLength, boolean includeMeta) { 122 String leadingLengths = ""; 123 String familyLength = kv.getFamilyLength() + " "; 124 if (includeMeta) { 125 leadingLengths += Strings.padFront(kv.getKeyLength() + "", '0', 4); 126 leadingLengths += " "; 127 leadingLengths += Strings.padFront(kv.getValueLength() + "", '0', 4); 128 leadingLengths += " "; 129 leadingLengths += Strings.padFront(kv.getRowLength() + "", '0', 2); 130 leadingLengths += " "; 131 } 132 int spacesAfterRow = maxRowLength - getRowString(kv).length() + 2; 133 int spacesAfterFamily = maxFamilyLength - getFamilyString(kv).length() + 2; 134 int spacesAfterQualifier = maxQualifierLength - getQualifierString(kv).length() + 1; 135 int spacesAfterTimestamp = 136 maxTimestampLength - Long.valueOf(kv.getTimestamp()).toString().length() + 1; 137 return leadingLengths + getRowString(kv) + StringUtils.repeat(' ', spacesAfterRow) 138 + familyLength + getFamilyString(kv) + StringUtils.repeat(' ', spacesAfterFamily) 139 + getQualifierString(kv) + StringUtils.repeat(' ', spacesAfterQualifier) 140 + getTimestampString(kv) + StringUtils.repeat(' ', spacesAfterTimestamp) + getTypeString(kv) 141 + " " + getValueString(kv); 142 } 143 144 protected static String getRowString(final KeyValue kv) { 145 return Bytes.toStringBinary(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength()); 146 } 147 148 protected static String getFamilyString(final KeyValue kv) { 149 return Bytes.toStringBinary(kv.getFamilyArray(), kv.getFamilyOffset(), kv.getFamilyLength()); 150 } 151 152 protected static String getQualifierString(final KeyValue kv) { 153 return Bytes.toStringBinary(kv.getQualifierArray(), kv.getQualifierOffset(), 154 kv.getQualifierLength()); 155 } 156 157 protected static String getTimestampString(final KeyValue kv) { 158 return kv.getTimestamp() + ""; 159 } 160 161 protected static String getTypeString(final KeyValue kv) { 162 return KeyValue.Type.codeToType(kv.getTypeByte()).toString(); 163 } 164 165 protected static String getValueString(final KeyValue kv) { 166 return Bytes.toStringBinary(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength()); 167 } 168 169}