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.util.vint;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.hbase.nio.ByteBuff;
28  import org.apache.hadoop.hbase.nio.SingleByteBuff;
29  
30  /**
31   * Simple Variable Length Integer encoding.  Left bit of 0 means we are on the last byte.  If left
32   * bit of the current byte is 1, then there is at least one more byte.
33   */
34  @InterfaceAudience.Private
35  public class UVLongTool{
36  
37    public static final byte
38      BYTE_7_RIGHT_BITS_SET = 127,
39      BYTE_LEFT_BIT_SET = -128;
40  
41    public static final long
42      LONG_7_RIGHT_BITS_SET = 127,
43      LONG_8TH_BIT_SET = 128;
44  
45    public static final byte[]
46      MAX_VALUE_BYTES = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1, 127 };
47  
48  
49    /********************* long -> bytes **************************/
50  
51    public static int numBytes(long in) {// do a check for illegal arguments if not protected
52      if (in == 0) {
53        return 1;
54      }// doesn't work with the formula below
55      return (70 - Long.numberOfLeadingZeros(in)) / 7;// 70 comes from 64+(7-1)
56    }
57  
58    public static byte[] getBytes(long value) {
59      int numBytes = numBytes(value);
60      byte[] bytes = new byte[numBytes];
61      long remainder = value;
62      for (int i = 0; i < numBytes - 1; ++i) {
63        bytes[i] = (byte) ((remainder & LONG_7_RIGHT_BITS_SET) | LONG_8TH_BIT_SET);// set the left bit
64        remainder >>= 7;
65      }
66      bytes[numBytes - 1] = (byte) (remainder & LONG_7_RIGHT_BITS_SET);// do not set the left bit
67      return bytes;
68    }
69  
70    public static int writeBytes(long value, OutputStream os) throws IOException {
71      int numBytes = numBytes(value);
72      long remainder = value;
73      for (int i = 0; i < numBytes - 1; ++i) {
74        // set the left bit
75        os.write((byte) ((remainder & LONG_7_RIGHT_BITS_SET) | LONG_8TH_BIT_SET));
76        remainder >>= 7;
77      }
78      // do not set the left bit
79      os.write((byte) (remainder & LONG_7_RIGHT_BITS_SET));
80      return numBytes;
81    }
82  
83    /******************** bytes -&gt; long **************************/
84  
85    public static long getLong(byte[] bytes) {
86      return getLong(new SingleByteBuff(ByteBuffer.wrap(bytes)), 0);
87    }
88  
89    public static long getLong(ByteBuff buf, int offset) {
90      long value = 0;
91      for (int i = 0;; ++i) {
92        byte b = buf.get(offset + i);
93        long shifted = BYTE_7_RIGHT_BITS_SET & b;// kill leftmost bit
94        shifted <<= 7 * i;
95        value |= shifted;
96        if (b >= 0) {
97          break;
98        }// first bit was 0, so that's the last byte in the VarLong
99      }
100     return value;
101   }
102 
103   public static long getLong(InputStream is) throws IOException {
104     long value = 0;
105     int i = 0;
106     int b;
107     do {
108       b = is.read();
109       long shifted = BYTE_7_RIGHT_BITS_SET & b;// kill leftmost bit
110       shifted <<= 7 * i;
111       value |= shifted;
112       ++i;
113     } while (b > Byte.MAX_VALUE);
114     return value;
115   }
116 }