This project has retired. For details please refer to its Attic page.
UnsafeArrayReads xref
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.giraph.utils;
20  
21  import java.io.IOException;
22  import java.lang.reflect.Field;
23  
24  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_BOOLEAN;
25  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_BYTE;
26  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_CHAR;
27  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_SHORT;
28  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_INT;
29  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_LONG;
30  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_FLOAT;
31  import static org.apache.giraph.utils.ByteUtils.SIZE_OF_DOUBLE;
32  
33  /**
34   * Byte array input stream that uses Unsafe methods to deserialize
35   * much faster
36   */
37  @edu.umd.cs.findbugs.annotations.SuppressWarnings(
38    "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT")
39  public class UnsafeArrayReads extends UnsafeReads {
40    /** Access to the unsafe class */
41    private static final sun.misc.Unsafe UNSAFE;
42    static {
43      try {
44        Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
45        field.setAccessible(true);
46        UNSAFE = (sun.misc.Unsafe) field.get(null);
47        // Checkstyle exception due to needing to check if unsafe is allowed
48        // CHECKSTYLE: stop IllegalCatch
49      } catch (Exception e) {
50        // CHECKSTYLE: resume IllegalCatch
51        throw new RuntimeException("UnsafeArrayReads: Failed to " +
52            "get unsafe", e);
53      }
54    }
55    /** Offset of a byte array */
56    private static final long BYTE_ARRAY_OFFSET  =
57        UNSAFE.arrayBaseOffset(byte[].class);
58  
59    /**
60     * Constructor
61     *
62     * @param buf Buffer to read from
63     */
64    public UnsafeArrayReads(byte[] buf) {
65      super(buf.length);
66      this.buffer = buf;
67    }
68  
69    /**
70     * Constructor.
71     *
72     * @param buf Buffer to read from
73     * @param offset Offsetin the buffer to start reading from
74     * @param length Max length of the buffer to read
75     */
76    public UnsafeArrayReads(byte[] buf, int offset, int length) {
77      super(offset, length);
78      this.buffer = buf;
79    }
80  
81    @Override
82    public int available() {
83      return (int) (limit - position);
84    }
85  
86    @Override
87    public boolean endOfInput() {
88      return available() == 0;
89    }
90  
91  
92    @Override
93    public int getPos() {
94      return (int) position;
95    }
96  
97    @Override
98    public void readFully(byte[] b) throws IOException {
99      require(b.length);
100     System.arraycopy(buffer, (int) position, b, 0, b.length);
101     position += b.length;
102   }
103 
104   @Override
105   public void readFully(byte[] b, int off, int len) throws IOException {
106     require(len);
107     System.arraycopy(buffer, (int) position, b, off, len);
108     position += len;
109   }
110 
111   @Override
112   public boolean readBoolean() {
113     require(SIZE_OF_BOOLEAN);
114     boolean value = UNSAFE.getBoolean(buffer,
115         BYTE_ARRAY_OFFSET + position);
116     position += SIZE_OF_BOOLEAN;
117     return value;
118   }
119 
120   @Override
121   public byte readByte() {
122     require(SIZE_OF_BYTE);
123     byte value = UNSAFE.getByte(buffer,
124         BYTE_ARRAY_OFFSET + position);
125     position += SIZE_OF_BYTE;
126     return value;
127   }
128 
129   @Override
130   public int readUnsignedByte() throws IOException {
131     return (short) (readByte() & 0xFF);
132   }
133 
134   @Override
135   public short readShort() {
136     require(SIZE_OF_SHORT);
137     short value = UNSAFE.getShort(buffer,
138         BYTE_ARRAY_OFFSET + position);
139     position += SIZE_OF_SHORT;
140     return value;
141   }
142 
143   @Override
144   public int readUnsignedShort() throws IOException {
145     return readShort() & 0xFFFF;
146   }
147 
148   @Override
149   public char readChar() {
150     require(SIZE_OF_CHAR);
151     char value = UNSAFE.getChar(buffer,
152         BYTE_ARRAY_OFFSET + position);
153     position += SIZE_OF_CHAR;
154     return value;
155   }
156 
157   @Override
158   public int readInt() {
159     require(SIZE_OF_INT);
160     int value = UNSAFE.getInt(buffer,
161         BYTE_ARRAY_OFFSET + position);
162     position += SIZE_OF_INT;
163     return value;
164   }
165 
166   @Override
167   public long readLong() {
168     require(SIZE_OF_LONG);
169     long value = UNSAFE.getLong(buffer,
170         BYTE_ARRAY_OFFSET + position);
171     position += SIZE_OF_LONG;
172     return value;
173   }
174 
175   @Override
176   public float readFloat() {
177     require(SIZE_OF_FLOAT);
178     float value = UNSAFE.getFloat(buffer,
179         BYTE_ARRAY_OFFSET + position);
180     position += SIZE_OF_FLOAT;
181     return value;
182   }
183 
184   @Override
185   public double readDouble() {
186     require(SIZE_OF_DOUBLE);
187     double value = UNSAFE.getDouble(buffer,
188         BYTE_ARRAY_OFFSET + position);
189     position += SIZE_OF_DOUBLE;
190     return value;
191   }
192 
193   /**
194    * Get an int at an arbitrary position in a byte[]
195    *
196    * @param buf Buffer to get the int from
197    * @param pos Position in the buffer to get the int from
198    * @return Int at the buffer position
199    */
200   public static int getInt(byte[] buf, int pos) {
201     return UNSAFE.getInt(buf,
202         BYTE_ARRAY_OFFSET + pos);
203   }
204 }