Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ImpalaStringWritable.java
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.cloudera.impala.hive.executor;
16 
17 import java.nio.ByteBuffer;
18 
20 
21 @SuppressWarnings("restriction")
31 public class ImpalaStringWritable {
32  // The length is 8 bytes into the struct.
33  static public final int STRING_VALUE_LEN_OFFSET = 8;
34 
35  // Ptr (to native heap) where the value should be read from and written to.
36  // This needs to be ABI compatible with the BE StringValue class
37  private final long stringValPtr_;
38 
39  // Array object to convert between native and java heap (i.e. byte[]).
40  private ByteBuffer array_;
41 
42  // Set if this object had to allocate from the native heap on the java side. If this
43  // is set, it will always be stringValPtr_->ptr
44  // We only need to allocate from the java side if we are trying to set the
45  // StringValue to a bigger size than what the native side allocated.
46  // If this object is used as a read-only input argument, this value will stay
47  // 0.
48  private long bufferPtr_;
49 
50  // Allocation size of stringValPtr_'s ptr.
51  private int bufferCapacity_;
52 
53  // Creates a string writable backed by a StringValue object. Ptr must be a valid
54  // StringValue (in the native heap).
55  public ImpalaStringWritable(long ptr) {
56  stringValPtr_ = ptr;
57  bufferPtr_= 0;
58  bufferCapacity_ = getLength();
59  array_ = ByteBuffer.allocate(0);
60  }
61 
62  /*
63  * Implement finalize() to clean up any allocations from the native heap.
64  */
65  @Override
66  protected void finalize() throws Throwable {
67  UnsafeUtil.UNSAFE.freeMemory(bufferPtr_);
68  super.finalize();
69  }
70 
71  // Returns the underlying bytes as a byte[]
72  public byte[] getBytes() {
73  int len = getLength();
74  // TODO: reuse this array.
75  array_ = ByteBuffer.allocate(len);
76  byte[] buffer = array_.array();
77 
78  long srcPtr = UnsafeUtil.UNSAFE.getLong(stringValPtr_);
79  UnsafeUtil.Copy(buffer, 0, srcPtr, len);
80  return buffer;
81  }
82 
83  // Returns the capacity of the underlying array
84  public int getCapacity() {
85  return bufferCapacity_;
86  }
87 
88  // Updates the new capacity. No-op if the new capacity is smaller.
89  public void setCapacity(int newCap) {
90  if (newCap <= bufferCapacity_) return;
91  bufferPtr_ = UnsafeUtil.UNSAFE.reallocateMemory(bufferPtr_, newCap);
92  UnsafeUtil.UNSAFE.putLong(stringValPtr_, bufferPtr_);
93  bufferCapacity_ = newCap;
94  }
95 
96  // Returns the length of the string
97  public int getLength() {
98  return UnsafeUtil.UNSAFE.getInt(stringValPtr_ + STRING_VALUE_LEN_OFFSET);
99  }
100 
101  // Updates the length of the string. If the new length is bigger,
102  // the additional bytes are undefined.
103  public void setSize(int s) {
104  setCapacity(s);
105  UnsafeUtil.UNSAFE.putInt(stringValPtr_ + 8, s);
106  }
107 
108  // Sets (v[offset], len) to the underlying buffer, growing it as necessary.
109  public void set(byte[] v, int offset, int len) {
110  setSize(len);
111  long strPtr = UnsafeUtil.UNSAFE.getLong(stringValPtr_);
112  UnsafeUtil.Copy(strPtr, v, offset, len);
113  }
114 }
uint8_t offset[7 *64-sizeof(uint64_t)]