Back to home page

OSCL-LXR

 
 

    


0001 /**
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements.  See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership.  The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License.  You may obtain a copy of the License at
0009  *
0010  *     http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing, software
0013  * distributed under the License is distributed on an "AS IS" BASIS,
0014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015  * See the License for the specific language governing permissions and
0016  * limitations under the License.
0017  */
0018 
0019 package org.apache.hive.service.cli;
0020 
0021 import java.nio.ByteBuffer;
0022 import java.util.AbstractList;
0023 import java.util.ArrayList;
0024 import java.util.Arrays;
0025 import java.util.BitSet;
0026 import java.util.List;
0027 
0028 import com.google.common.primitives.Booleans;
0029 import com.google.common.primitives.Bytes;
0030 import com.google.common.primitives.Doubles;
0031 import com.google.common.primitives.Ints;
0032 import com.google.common.primitives.Longs;
0033 import com.google.common.primitives.Shorts;
0034 import org.apache.hive.service.cli.thrift.TBinaryColumn;
0035 import org.apache.hive.service.cli.thrift.TBoolColumn;
0036 import org.apache.hive.service.cli.thrift.TByteColumn;
0037 import org.apache.hive.service.cli.thrift.TColumn;
0038 import org.apache.hive.service.cli.thrift.TDoubleColumn;
0039 import org.apache.hive.service.cli.thrift.TI16Column;
0040 import org.apache.hive.service.cli.thrift.TI32Column;
0041 import org.apache.hive.service.cli.thrift.TI64Column;
0042 import org.apache.hive.service.cli.thrift.TStringColumn;
0043 
0044 /**
0045  * Column.
0046  */
0047 public class Column extends AbstractList {
0048 
0049   private static final int DEFAULT_SIZE = 100;
0050 
0051   private final Type type;
0052 
0053   private BitSet nulls;
0054 
0055   private int size;
0056   private boolean[] boolVars;
0057   private byte[] byteVars;
0058   private short[] shortVars;
0059   private int[] intVars;
0060   private long[] longVars;
0061   private double[] doubleVars;
0062   private List<String> stringVars;
0063   private List<ByteBuffer> binaryVars;
0064 
0065   public Column(Type type, BitSet nulls, Object values) {
0066     this.type = type;
0067     this.nulls = nulls;
0068     if (type == Type.BOOLEAN_TYPE) {
0069       boolVars = (boolean[]) values;
0070       size = boolVars.length;
0071     } else if (type == Type.TINYINT_TYPE) {
0072       byteVars = (byte[]) values;
0073       size = byteVars.length;
0074     } else if (type == Type.SMALLINT_TYPE) {
0075       shortVars = (short[]) values;
0076       size = shortVars.length;
0077     } else if (type == Type.INT_TYPE) {
0078       intVars = (int[]) values;
0079       size = intVars.length;
0080     } else if (type == Type.BIGINT_TYPE) {
0081       longVars = (long[]) values;
0082       size = longVars.length;
0083     } else if (type == Type.DOUBLE_TYPE) {
0084       doubleVars = (double[]) values;
0085       size = doubleVars.length;
0086     } else if (type == Type.BINARY_TYPE) {
0087       binaryVars = (List<ByteBuffer>) values;
0088       size = binaryVars.size();
0089     } else if (type == Type.STRING_TYPE) {
0090       stringVars = (List<String>) values;
0091       size = stringVars.size();
0092     } else {
0093       throw new IllegalStateException("invalid union object");
0094     }
0095   }
0096 
0097   public Column(Type type) {
0098     nulls = new BitSet();
0099     switch (type) {
0100       case BOOLEAN_TYPE:
0101         boolVars = new boolean[DEFAULT_SIZE];
0102         break;
0103       case TINYINT_TYPE:
0104         byteVars = new byte[DEFAULT_SIZE];
0105         break;
0106       case SMALLINT_TYPE:
0107         shortVars = new short[DEFAULT_SIZE];
0108         break;
0109       case INT_TYPE:
0110         intVars = new int[DEFAULT_SIZE];
0111         break;
0112       case BIGINT_TYPE:
0113         longVars = new long[DEFAULT_SIZE];
0114         break;
0115       case FLOAT_TYPE:
0116       case DOUBLE_TYPE:
0117         type = Type.DOUBLE_TYPE;
0118         doubleVars = new double[DEFAULT_SIZE];
0119         break;
0120       case BINARY_TYPE:
0121         binaryVars = new ArrayList<ByteBuffer>();
0122         break;
0123       default:
0124         type = Type.STRING_TYPE;
0125         stringVars = new ArrayList<String>();
0126     }
0127     this.type = type;
0128   }
0129 
0130   public Column(TColumn colValues) {
0131     if (colValues.isSetBoolVal()) {
0132       type = Type.BOOLEAN_TYPE;
0133       nulls = toBitset(colValues.getBoolVal().getNulls());
0134       boolVars = Booleans.toArray(colValues.getBoolVal().getValues());
0135       size = boolVars.length;
0136     } else if (colValues.isSetByteVal()) {
0137       type = Type.TINYINT_TYPE;
0138       nulls = toBitset(colValues.getByteVal().getNulls());
0139       byteVars = Bytes.toArray(colValues.getByteVal().getValues());
0140       size = byteVars.length;
0141     } else if (colValues.isSetI16Val()) {
0142       type = Type.SMALLINT_TYPE;
0143       nulls = toBitset(colValues.getI16Val().getNulls());
0144       shortVars = Shorts.toArray(colValues.getI16Val().getValues());
0145       size = shortVars.length;
0146     } else if (colValues.isSetI32Val()) {
0147       type = Type.INT_TYPE;
0148       nulls = toBitset(colValues.getI32Val().getNulls());
0149       intVars = Ints.toArray(colValues.getI32Val().getValues());
0150       size = intVars.length;
0151     } else if (colValues.isSetI64Val()) {
0152       type = Type.BIGINT_TYPE;
0153       nulls = toBitset(colValues.getI64Val().getNulls());
0154       longVars = Longs.toArray(colValues.getI64Val().getValues());
0155       size = longVars.length;
0156     } else if (colValues.isSetDoubleVal()) {
0157       type = Type.DOUBLE_TYPE;
0158       nulls = toBitset(colValues.getDoubleVal().getNulls());
0159       doubleVars = Doubles.toArray(colValues.getDoubleVal().getValues());
0160       size = doubleVars.length;
0161     } else if (colValues.isSetBinaryVal()) {
0162       type = Type.BINARY_TYPE;
0163       nulls = toBitset(colValues.getBinaryVal().getNulls());
0164       binaryVars = colValues.getBinaryVal().getValues();
0165       size = binaryVars.size();
0166     } else if (colValues.isSetStringVal()) {
0167       type = Type.STRING_TYPE;
0168       nulls = toBitset(colValues.getStringVal().getNulls());
0169       stringVars = colValues.getStringVal().getValues();
0170       size = stringVars.size();
0171     } else {
0172       throw new IllegalStateException("invalid union object");
0173     }
0174   }
0175 
0176   public Column extractSubset(int start, int end) {
0177     BitSet subNulls = nulls.get(start, end);
0178     if (type == Type.BOOLEAN_TYPE) {
0179       Column subset = new Column(type, subNulls, Arrays.copyOfRange(boolVars, start, end));
0180       boolVars = Arrays.copyOfRange(boolVars, end, size);
0181       nulls = nulls.get(start, size);
0182       size = boolVars.length;
0183       return subset;
0184     }
0185     if (type == Type.TINYINT_TYPE) {
0186       Column subset = new Column(type, subNulls, Arrays.copyOfRange(byteVars, start, end));
0187       byteVars = Arrays.copyOfRange(byteVars, end, size);
0188       nulls = nulls.get(start, size);
0189       size = byteVars.length;
0190       return subset;
0191     }
0192     if (type == Type.SMALLINT_TYPE) {
0193       Column subset = new Column(type, subNulls, Arrays.copyOfRange(shortVars, start, end));
0194       shortVars = Arrays.copyOfRange(shortVars, end, size);
0195       nulls = nulls.get(start, size);
0196       size = shortVars.length;
0197       return subset;
0198     }
0199     if (type == Type.INT_TYPE) {
0200       Column subset = new Column(type, subNulls, Arrays.copyOfRange(intVars, start, end));
0201       intVars = Arrays.copyOfRange(intVars, end, size);
0202       nulls = nulls.get(start, size);
0203       size = intVars.length;
0204       return subset;
0205     }
0206     if (type == Type.BIGINT_TYPE) {
0207       Column subset = new Column(type, subNulls, Arrays.copyOfRange(longVars, start, end));
0208       longVars = Arrays.copyOfRange(longVars, end, size);
0209       nulls = nulls.get(start, size);
0210       size = longVars.length;
0211       return subset;
0212     }
0213     if (type == Type.DOUBLE_TYPE) {
0214       Column subset = new Column(type, subNulls, Arrays.copyOfRange(doubleVars, start, end));
0215       doubleVars = Arrays.copyOfRange(doubleVars, end, size);
0216       nulls = nulls.get(start, size);
0217       size = doubleVars.length;
0218       return subset;
0219     }
0220     if (type == Type.BINARY_TYPE) {
0221       Column subset = new Column(type, subNulls, binaryVars.subList(start, end));
0222       binaryVars = binaryVars.subList(end, binaryVars.size());
0223       nulls = nulls.get(start, size);
0224       size = binaryVars.size();
0225       return subset;
0226     }
0227     if (type == Type.STRING_TYPE) {
0228       Column subset = new Column(type, subNulls, stringVars.subList(start, end));
0229       stringVars = stringVars.subList(end, stringVars.size());
0230       nulls = nulls.get(start, size);
0231       size = stringVars.size();
0232       return subset;
0233     }
0234     throw new IllegalStateException("invalid union object");
0235   }
0236 
0237   private static final byte[] MASKS = new byte[] {
0238       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, (byte)0x80
0239   };
0240 
0241   private static BitSet toBitset(byte[] nulls) {
0242     BitSet bitset = new BitSet();
0243     int bits = nulls.length * 8;
0244     for (int i = 0; i < bits; i++) {
0245       bitset.set(i, (nulls[i / 8] & MASKS[i % 8]) != 0);
0246     }
0247     return bitset;
0248   }
0249 
0250   private static byte[] toBinary(BitSet bitset) {
0251     byte[] nulls = new byte[1 + (bitset.length() / 8)];
0252     for (int i = 0; i < bitset.length(); i++) {
0253       nulls[i / 8] |= bitset.get(i) ? MASKS[i % 8] : 0;
0254     }
0255     return nulls;
0256   }
0257 
0258   public Type getType() {
0259     return type;
0260   }
0261 
0262   @Override
0263   public Object get(int index) {
0264     if (nulls.get(index)) {
0265       return null;
0266     }
0267     switch (type) {
0268       case BOOLEAN_TYPE:
0269         return boolVars[index];
0270       case TINYINT_TYPE:
0271         return byteVars[index];
0272       case SMALLINT_TYPE:
0273         return shortVars[index];
0274       case INT_TYPE:
0275         return intVars[index];
0276       case BIGINT_TYPE:
0277         return longVars[index];
0278       case DOUBLE_TYPE:
0279         return doubleVars[index];
0280       case STRING_TYPE:
0281         return stringVars.get(index);
0282       case BINARY_TYPE:
0283         return binaryVars.get(index).array();
0284     }
0285     return null;
0286   }
0287 
0288   @Override
0289   public int size() {
0290     return size;
0291   }
0292 
0293   public TColumn toTColumn() {
0294     TColumn value = new TColumn();
0295     ByteBuffer nullMasks = ByteBuffer.wrap(toBinary(nulls));
0296     switch (type) {
0297       case BOOLEAN_TYPE:
0298         value.setBoolVal(new TBoolColumn(Booleans.asList(Arrays.copyOfRange(boolVars, 0, size)), nullMasks));
0299         break;
0300       case TINYINT_TYPE:
0301         value.setByteVal(new TByteColumn(Bytes.asList(Arrays.copyOfRange(byteVars, 0, size)), nullMasks));
0302         break;
0303       case SMALLINT_TYPE:
0304         value.setI16Val(new TI16Column(Shorts.asList(Arrays.copyOfRange(shortVars, 0, size)), nullMasks));
0305         break;
0306       case INT_TYPE:
0307         value.setI32Val(new TI32Column(Ints.asList(Arrays.copyOfRange(intVars, 0, size)), nullMasks));
0308         break;
0309       case BIGINT_TYPE:
0310         value.setI64Val(new TI64Column(Longs.asList(Arrays.copyOfRange(longVars, 0, size)), nullMasks));
0311         break;
0312       case DOUBLE_TYPE:
0313         value.setDoubleVal(new TDoubleColumn(Doubles.asList(Arrays.copyOfRange(doubleVars, 0, size)), nullMasks));
0314         break;
0315       case STRING_TYPE:
0316         value.setStringVal(new TStringColumn(stringVars, nullMasks));
0317         break;
0318       case BINARY_TYPE:
0319         value.setBinaryVal(new TBinaryColumn(binaryVars, nullMasks));
0320         break;
0321     }
0322     return value;
0323   }
0324 
0325   private static final ByteBuffer EMPTY_BINARY = ByteBuffer.allocate(0);
0326   private static final String EMPTY_STRING = "";
0327 
0328   public void addValue(Type type, Object field) {
0329     switch (type) {
0330       case BOOLEAN_TYPE:
0331         nulls.set(size, field == null);
0332         boolVars()[size] = field == null ? true : (Boolean)field;
0333         break;
0334       case TINYINT_TYPE:
0335         nulls.set(size, field == null);
0336         byteVars()[size] = field == null ? 0 : (Byte) field;
0337         break;
0338       case SMALLINT_TYPE:
0339         nulls.set(size, field == null);
0340         shortVars()[size] = field == null ? 0 : (Short)field;
0341         break;
0342       case INT_TYPE:
0343         nulls.set(size, field == null);
0344         intVars()[size] = field == null ? 0 : (Integer)field;
0345         break;
0346       case BIGINT_TYPE:
0347         nulls.set(size, field == null);
0348         longVars()[size] = field == null ? 0 : (Long)field;
0349         break;
0350       case FLOAT_TYPE:
0351         nulls.set(size, field == null);
0352         doubleVars()[size] = field == null ? 0 : Double.valueOf(field.toString());
0353         break;
0354       case DOUBLE_TYPE:
0355         nulls.set(size, field == null);
0356         doubleVars()[size] = field == null ? 0 : (Double)field;
0357         break;
0358       case BINARY_TYPE:
0359         nulls.set(binaryVars.size(), field == null);
0360         binaryVars.add(field == null ? EMPTY_BINARY : ByteBuffer.wrap((byte[])field));
0361         break;
0362       default:
0363         nulls.set(stringVars.size(), field == null);
0364         stringVars.add(field == null ? EMPTY_STRING : String.valueOf(field));
0365         break;
0366     }
0367     size++;
0368   }
0369 
0370   private boolean[] boolVars() {
0371     if (boolVars.length == size) {
0372       boolean[] newVars = new boolean[size << 1];
0373       System.arraycopy(boolVars, 0, newVars, 0, size);
0374       return boolVars = newVars;
0375     }
0376     return boolVars;
0377   }
0378 
0379   private byte[] byteVars() {
0380     if (byteVars.length == size) {
0381       byte[] newVars = new byte[size << 1];
0382       System.arraycopy(byteVars, 0, newVars, 0, size);
0383       return byteVars = newVars;
0384     }
0385     return byteVars;
0386   }
0387 
0388   private short[] shortVars() {
0389     if (shortVars.length == size) {
0390       short[] newVars = new short[size << 1];
0391       System.arraycopy(shortVars, 0, newVars, 0, size);
0392       return shortVars = newVars;
0393     }
0394     return shortVars;
0395   }
0396 
0397   private int[] intVars() {
0398     if (intVars.length == size) {
0399       int[] newVars = new int[size << 1];
0400       System.arraycopy(intVars, 0, newVars, 0, size);
0401       return intVars = newVars;
0402     }
0403     return intVars;
0404   }
0405 
0406   private long[] longVars() {
0407     if (longVars.length == size) {
0408       long[] newVars = new long[size << 1];
0409       System.arraycopy(longVars, 0, newVars, 0, size);
0410       return longVars = newVars;
0411     }
0412     return longVars;
0413   }
0414 
0415   private double[] doubleVars() {
0416     if (doubleVars.length == size) {
0417       double[] newVars = new double[size << 1];
0418       System.arraycopy(doubleVars, 0, newVars, 0, size);
0419       return doubleVars = newVars;
0420     }
0421     return doubleVars;
0422   }
0423 }