View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase;
20  
21  import java.nio.ByteBuffer;
22  import java.util.Collection;
23  import java.util.List;
24  
25  import org.apache.hadoop.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.util.Bytes;
27  import org.apache.hadoop.hbase.util.IterableUtils;
28  import org.apache.hadoop.hbase.util.Strings;
29  
30  import com.google.common.collect.Lists;
31  
32  @InterfaceAudience.Private
33  public class KeyValueTestUtil {
34  
35    public static KeyValue create(
36        String row,
37        String family,
38        String qualifier,
39        long timestamp,
40        String value)
41    {
42      return create(row, family, qualifier, timestamp, KeyValue.Type.Put, value);
43    }
44  
45    public static KeyValue create(
46        String row,
47        String family,
48        String qualifier,
49        long timestamp,
50        KeyValue.Type type,
51        String value)
52    {
53        return new KeyValue(
54            Bytes.toBytes(row),
55            Bytes.toBytes(family),
56            Bytes.toBytes(qualifier),
57            timestamp,
58            type,
59            Bytes.toBytes(value)
60        );
61    }
62  
63    public static ByteBuffer toByteBufferAndRewind(final Iterable<? extends KeyValue> kvs,
64        boolean includeMemstoreTS) {
65      int totalBytes = KeyValueUtil.totalLengthWithMvccVersion(kvs, includeMemstoreTS);
66      ByteBuffer bb = ByteBuffer.allocate(totalBytes);
67      for (KeyValue kv : IterableUtils.nullSafe(kvs)) {
68        KeyValueUtil.appendToByteBuffer(bb, kv, includeMemstoreTS);
69      }
70      bb.rewind();
71      return bb;
72    }
73  
74    /**
75     * Checks whether KeyValues from kvCollection2 are contained in kvCollection1.
76     * 
77     * The comparison is made without distinguishing MVCC version of the KeyValues
78     * 
79     * @param kvCollection1
80     * @param kvCollection2
81     * @return true if KeyValues from kvCollection2 are contained in kvCollection1
82     */
83    public static boolean containsIgnoreMvccVersion(Collection<? extends Cell> kvCollection1,
84        Collection<? extends Cell> kvCollection2) {
85      for (Cell kv1 : kvCollection1) {
86        boolean found = false;
87        for (Cell kv2 : kvCollection2) {
88          if (CellComparator.equalsIgnoreMvccVersion(kv1, kv2)) found = true;
89        }
90        if (!found) return false;
91      }
92      return true;
93    }
94    
95    public static List<KeyValue> rewindThenToList(final ByteBuffer bb,
96        final boolean includesMemstoreTS, final boolean useTags) {
97      bb.rewind();
98      List<KeyValue> kvs = Lists.newArrayList();
99      KeyValue kv = null;
100     while (true) {
101       kv = KeyValueUtil.nextShallowCopy(bb, includesMemstoreTS, useTags);
102       if (kv == null) {
103         break;
104       }
105       kvs.add(kv);
106     }
107     return kvs;
108   }
109 
110 
111   /********************* toString ************************************/
112 
113   public static String toStringWithPadding(final Collection<? extends KeyValue> kvs,
114       final boolean includeMeta) {
115     int maxRowStringLength = 0;
116     int maxFamilyStringLength = 0;
117     int maxQualifierStringLength = 0;
118     int maxTimestampLength = 0;
119     for (KeyValue kv : kvs) {
120       maxRowStringLength = Math.max(maxRowStringLength, getRowString(kv).length());
121       maxFamilyStringLength = Math.max(maxFamilyStringLength, getFamilyString(kv).length());
122       maxQualifierStringLength = Math.max(maxQualifierStringLength, getQualifierString(kv)
123         .length());
124       maxTimestampLength = Math.max(maxTimestampLength, Long.valueOf(kv.getTimestamp()).toString()
125         .length());
126     }
127     StringBuilder sb = new StringBuilder();
128     for (KeyValue kv : kvs) {
129       if (sb.length() > 0) {
130         sb.append("\n");
131       }
132       String row = toStringWithPadding(kv, maxRowStringLength, maxFamilyStringLength,
133         maxQualifierStringLength, maxTimestampLength, includeMeta);
134       sb.append(row);
135     }
136     return sb.toString();
137   }
138 
139   protected static String toStringWithPadding(final KeyValue kv, final int maxRowLength,
140       int maxFamilyLength, int maxQualifierLength, int maxTimestampLength, boolean includeMeta) {
141     String leadingLengths = "";
142     String familyLength = kv.getFamilyLength() + " ";
143     if (includeMeta) {
144       leadingLengths += Strings.padFront(kv.getKeyLength() + "", '0', 4);
145       leadingLengths += " ";
146       leadingLengths += Strings.padFront(kv.getValueLength() + "", '0', 4);
147       leadingLengths += " ";
148       leadingLengths += Strings.padFront(kv.getRowLength() + "", '0', 2);
149       leadingLengths += " ";
150     }
151     int spacesAfterRow = maxRowLength - getRowString(kv).length() + 2;
152     int spacesAfterFamily = maxFamilyLength - getFamilyString(kv).length() + 2;
153     int spacesAfterQualifier = maxQualifierLength - getQualifierString(kv).length() + 1;
154     int spacesAfterTimestamp = maxTimestampLength
155         - Long.valueOf(kv.getTimestamp()).toString().length() + 1;
156     return leadingLengths + getRowString(kv) + Strings.repeat(' ', spacesAfterRow)
157         + familyLength + getFamilyString(kv) + Strings.repeat(' ', spacesAfterFamily)
158         + getQualifierString(kv) + Strings.repeat(' ', spacesAfterQualifier)
159         + getTimestampString(kv) + Strings.repeat(' ', spacesAfterTimestamp)
160         + getTypeString(kv) + " " + getValueString(kv);
161   }
162 
163   protected static String getRowString(final KeyValue kv) {
164     return Bytes.toStringBinary(kv.getRow());
165   }
166 
167   protected static String getFamilyString(final KeyValue kv) {
168     return Bytes.toStringBinary(kv.getFamily());
169   }
170 
171   protected static String getQualifierString(final KeyValue kv) {
172     return Bytes.toStringBinary(kv.getQualifier());
173   }
174 
175   protected static String getTimestampString(final KeyValue kv) {
176     return kv.getTimestamp() + "";
177   }
178 
179   protected static String getTypeString(final KeyValue kv) {
180     return KeyValue.Type.codeToType(kv.getType()).toString();
181   }
182 
183   protected static String getValueString(final KeyValue kv) {
184     return Bytes.toStringBinary(kv.getValue());
185   }
186 
187 }