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.thrift;
20  
21  import static org.apache.hadoop.hbase.util.Bytes.getBytes;
22  
23  import java.nio.ByteBuffer;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.TreeMap;
28
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  import org.apache.hadoop.hbase.Cell;
31  import org.apache.hadoop.hbase.CellUtil;
32  import org.apache.hadoop.hbase.HColumnDescriptor;
33  import org.apache.hadoop.hbase.KeyValue;
34  import org.apache.hadoop.hbase.client.Append;
35  import org.apache.hadoop.hbase.client.Increment;
36  import org.apache.hadoop.hbase.client.Result;
37  import org.apache.hadoop.hbase.io.compress.Compression;
38  import org.apache.hadoop.hbase.regionserver.BloomType;
39  import org.apache.hadoop.hbase.thrift.generated.ColumnDescriptor;
40  import org.apache.hadoop.hbase.thrift.generated.IllegalArgument;
41  import org.apache.hadoop.hbase.thrift.generated.TAppend;
42  import org.apache.hadoop.hbase.thrift.generated.TCell;
43  import org.apache.hadoop.hbase.thrift.generated.TColumn;
44  import org.apache.hadoop.hbase.thrift.generated.TIncrement;
45  import org.apache.hadoop.hbase.thrift.generated.TRowResult;
46  import org.apache.hadoop.hbase.util.Bytes;
47
48  @InterfaceAudience.Private
49  public class ThriftUtilities {
50
51    /**
52     * This utility method creates a new Hbase HColumnDescriptor object based on a
53     * Thrift ColumnDescriptor "struct".
54     *
55     * @param in
56     *          Thrift ColumnDescriptor object
57     * @return HColumnDescriptor
58     * @throws IllegalArgument
59     */
60    static public HColumnDescriptor colDescFromThrift(ColumnDescriptor in)
61        throws IllegalArgument {
62      Compression.Algorithm comp =
63        Compression.getCompressionAlgorithmByName(in.compression.toLowerCase(Locale.ROOT));
64      BloomType bt =
65        BloomType.valueOf(in.bloomFilterType);
66
67      if (in.name == null || !in.name.hasRemaining()) {
68        throw new IllegalArgument("column name is empty");
69      }
70      byte [] parsedName = KeyValue.parseColumn(Bytes.getBytes(in.name))[0];
71      HColumnDescriptor col = new HColumnDescriptor(parsedName)
72          .setMaxVersions(in.maxVersions)
73          .setCompressionType(comp)
74          .setInMemory(in.inMemory)
75          .setBlockCacheEnabled(in.blockCacheEnabled)
76          .setTimeToLive(in.timeToLive > 0 ? in.timeToLive : Integer.MAX_VALUE)
77          .setBloomFilterType(bt);
78      return col;
79    }
80
81    /**
82     * This utility method creates a new Thrift ColumnDescriptor "struct" based on
83     * an Hbase HColumnDescriptor object.
84     *
85     * @param in
86     *          Hbase HColumnDescriptor object
87     * @return Thrift ColumnDescriptor
88     */
89    static public ColumnDescriptor colDescFromHbase(HColumnDescriptor in) {
90      ColumnDescriptor col = new ColumnDescriptor();
91      col.name = ByteBuffer.wrap(Bytes.add(in.getName(), KeyValue.COLUMN_FAMILY_DELIM_ARRAY));
92      col.maxVersions = in.getMaxVersions();
93      col.compression = in.getCompressionType().toString();
94      col.inMemory = in.isInMemory();
95      col.blockCacheEnabled = in.isBlockCacheEnabled();
96      col.bloomFilterType = in.getBloomFilterType().toString();
97      col.timeToLive = in.getTimeToLive();
98      return col;
99    }
100
101   /**
102    * This utility method creates a list of Thrift TCell "struct" based on
103    * an Hbase Cell object. The empty list is returned if the input is null.
104    *
105    * @param in
106    *          Hbase Cell object
107    * @return Thrift TCell array
108    */
109   static public List<TCell> cellFromHBase(Cell in) {
110     List<TCell> list = new ArrayList<TCell>(1);
111     if (in != null) {
112       list.add(new TCell(ByteBuffer.wrap(CellUtil.cloneValue(in)), in.getTimestamp()));
113     }
114     return list;
115   }
116
117   /**
118    * This utility method creates a list of Thrift TCell "struct" based on
119    * an Hbase Cell array. The empty list is returned if the input is null.
120    * @param in Hbase Cell array
121    * @return Thrift TCell array
122    */
123   static public List<TCell> cellFromHBase(Cell[] in) {
124     List<TCell> list = null;
125     if (in != null) {
126       list = new ArrayList<TCell>(in.length);
127       for (int i = 0; i < in.length; i++) {
128         list.add(new TCell(ByteBuffer.wrap(CellUtil.cloneValue(in[i])), in[i].getTimestamp()));
129       }
130     } else {
131       list = new ArrayList<TCell>(0);
132     }
133     return list;
134   }
135
136   /**
137    * This utility method creates a list of Thrift TRowResult "struct" based on
138    * an Hbase RowResult object. The empty list is returned if the input is
139    * null.
140    *
141    * @param in
142    *          Hbase RowResult object
143    * @param sortColumns
144    *          This boolean dictates if row data is returned in a sorted order
145    *          sortColumns = True will set TRowResult's sortedColumns member
146    *                        which is an ArrayList of TColumn struct
147    *          sortColumns = False will set TRowResult's columns member which is
148    *                        a map of columnName and TCell struct
149    * @return Thrift TRowResult array
150    */
151   static public List<TRowResult> rowResultFromHBase(Result[] in, boolean sortColumns) {
152     List<TRowResult> results = new ArrayList<TRowResult>();
153     for ( Result result_ : in) {
154         if(result_ == null || result_.isEmpty()) {
155             continue;
156         }
157         TRowResult result = new TRowResult();
158         result.row = ByteBuffer.wrap(result_.getRow());
159         if (sortColumns) {
160           result.sortedColumns = new ArrayList<TColumn>();
161           for (Cell kv : result_.rawCells()) {
162             result.sortedColumns.add(new TColumn(
163                 ByteBuffer.wrap(KeyValue.makeColumn(CellUtil.cloneFamily(kv),
164                     CellUtil.cloneQualifier(kv))),
165                 new TCell(ByteBuffer.wrap(CellUtil.cloneValue(kv)), kv.getTimestamp())));
166           }
167         } else {
168           result.columns = new TreeMap<ByteBuffer, TCell>();
169           for (Cell kv : result_.rawCells()) {
170             result.columns.put(
171                 ByteBuffer.wrap(KeyValue.makeColumn(CellUtil.cloneFamily(kv),
172                     CellUtil.cloneQualifier(kv))),
173                 new TCell(ByteBuffer.wrap(CellUtil.cloneValue(kv)), kv.getTimestamp()));
174           }
175         }
176       results.add(result);
177     }
178     return results;
179   }
180
181   /**
182    * This utility method creates a list of Thrift TRowResult "struct" based on
183    * an array of Hbase RowResult objects. The empty list is returned if the input is
184    * null.
185    *
186    * @param in
187    *          Array of Hbase RowResult objects
188    * @return Thrift TRowResult array
189    */
190   static public List<TRowResult> rowResultFromHBase(Result[] in) {
191     return rowResultFromHBase(in, false);
192   }
193
194   static public List<TRowResult> rowResultFromHBase(Result in) {
195     Result [] result = { in };
196     return rowResultFromHBase(result);
197   }
198
199   /**
200    * From a {@link TIncrement} create an {@link Increment}.
201    * @param tincrement the Thrift version of an increment
202    * @return an increment that the {@link TIncrement} represented.
203    */
204   public static Increment incrementFromThrift(TIncrement tincrement) {
205     Increment inc = new Increment(tincrement.getRow());
206     byte[][] famAndQf = KeyValue.parseColumn(tincrement.getColumn());
207     if (famAndQf.length != 2) return null;
208     inc.addColumn(famAndQf[0], famAndQf[1], tincrement.getAmmount());
209     return inc;
210   }
211
212   /**
213    * From a {@link TAppend} create an {@link Append}.
214    * @param tappend the Thrift version of an append.
215    * @return an increment that the {@link TAppend} represented.
216    */
217   public static Append appendFromThrift(TAppend tappend) {
218     Append append = new Append(tappend.getRow());
219     List<ByteBuffer> columns = tappend.getColumns();
220     List<ByteBuffer> values = tappend.getValues();
221
222     if (columns.size() != values.size()) {
223       throw new IllegalArgumentException(
224           "Sizes of columns and values in tappend object are not matching");
225     }
226
227     int length = columns.size();
228
229     for (int i = 0; i < length; i++) {
230       byte[][] famAndQf = KeyValue.parseColumn(getBytes(columns.get(i)));
231       append.add(famAndQf[0], famAndQf[1], getBytes(values.get(i)));
232     }
233     return append;
234   }
235 }