Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
bit-stream-utils.inline.h
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 
16 #ifndef IMPALA_UTIL_BIT_STREAM_UTILS_INLINE_H
17 #define IMPALA_UTIL_BIT_STREAM_UTILS_INLINE_H
18 
19 #include "util/bit-stream-utils.h"
20 
21 namespace impala {
22 
23 inline bool BitWriter::PutValue(uint64_t v, int num_bits) {
24  // TODO: revisit this limit if necessary (can be raised to 64 by fixing some edge cases)
25  DCHECK_LE(num_bits, 32);
26  DCHECK_EQ(v >> num_bits, 0) << "v = " << v << ", num_bits = " << num_bits;
27 
28  if (UNLIKELY(byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8)) return false;
29 
31  bit_offset_ += num_bits;
32 
33  if (UNLIKELY(bit_offset_ >= 64)) {
34  // Flush buffered_values_ and write out bits of v that did not fit
35  memcpy(buffer_ + byte_offset_, &buffered_values_, 8);
36  buffered_values_ = 0;
37  byte_offset_ += 8;
38  bit_offset_ -= 64;
39  buffered_values_ = v >> (num_bits - bit_offset_);
40  }
41  DCHECK_LT(bit_offset_, 64);
42  return true;
43 }
44 
45 inline void BitWriter::Flush(bool align) {
46  int num_bytes = BitUtil::Ceil(bit_offset_, 8);
47  DCHECK_LE(byte_offset_ + num_bytes, max_bytes_);
48  memcpy(buffer_ + byte_offset_, &buffered_values_, num_bytes);
49 
50  if (align) {
51  buffered_values_ = 0;
52  byte_offset_ += num_bytes;
53  bit_offset_ = 0;
54  }
55 }
56 
57 inline uint8_t* BitWriter::GetNextBytePtr(int num_bytes) {
58  Flush(/* align */ true);
59  DCHECK_LE(byte_offset_, max_bytes_);
60  if (byte_offset_ + num_bytes > max_bytes_) return NULL;
61  uint8_t* ptr = buffer_ + byte_offset_;
62  byte_offset_ += num_bytes;
63  return ptr;
64 }
65 
66 template<typename T>
67 inline bool BitWriter::PutAligned(T val, int num_bytes) {
68  uint8_t* ptr = GetNextBytePtr(num_bytes);
69  if (ptr == NULL) return false;
70  memcpy(ptr, &val, num_bytes);
71  return true;
72 }
73 
74 inline bool BitWriter::PutVlqInt(int32_t v) {
75  bool result = true;
76  while ((v & 0xFFFFFF80) != 0L) {
77  result &= PutAligned<uint8_t>((v & 0x7F) | 0x80, 1);
78  v >>= 7;
79  }
80  result &= PutAligned<uint8_t>(v & 0x7F, 1);
81  return result;
82 }
83 
84 template<typename T>
85 inline bool BitReader::GetValue(int num_bits, T* v) {
86  // TODO: revisit this limit if necessary
87  DCHECK_LE(num_bits, 32);
88  DCHECK_LE(num_bits, sizeof(T) * 8);
89 
90  if (UNLIKELY(byte_offset_ * 8 + bit_offset_ + num_bits > max_bytes_ * 8)) return false;
91 
93 
94  bit_offset_ += num_bits;
95  if (bit_offset_ >= 64) {
96  byte_offset_ += 8;
97  bit_offset_ -= 64;
98 
99  int bytes_remaining = max_bytes_ - byte_offset_;
100  if (LIKELY(bytes_remaining >= 8)) {
101  memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
102  } else {
103  memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
104  }
105 
106  // Read bits of v that crossed into new buffered_values_
108  << (num_bits - bit_offset_);
109  }
110  DCHECK_LE(bit_offset_, 64);
111  return true;
112 }
113 
114 template<typename T>
115 inline bool BitReader::GetAligned(int num_bytes, T* v) {
116  DCHECK_LE(num_bytes, sizeof(T));
117  int bytes_read = BitUtil::Ceil(bit_offset_, 8);
118  if (UNLIKELY(byte_offset_ + bytes_read + num_bytes > max_bytes_)) return false;
119 
120  // Advance byte_offset to next unread byte and read num_bytes
121  byte_offset_ += bytes_read;
122  memcpy(v, buffer_ + byte_offset_, num_bytes);
123  byte_offset_ += num_bytes;
124 
125  // Reset buffered_values_
126  bit_offset_ = 0;
127  int bytes_remaining = max_bytes_ - byte_offset_;
128  if (LIKELY(bytes_remaining >= 8)) {
129  memcpy(&buffered_values_, buffer_ + byte_offset_, 8);
130  } else {
131  memcpy(&buffered_values_, buffer_ + byte_offset_, bytes_remaining);
132  }
133  return true;
134 }
135 
136 inline bool BitReader::GetVlqInt(int32_t* v) {
137  *v = 0;
138  int shift = 0;
139  int num_bytes = 0;
140  uint8_t byte = 0;
141  do {
142  if (!GetAligned<uint8_t>(1, &byte)) return false;
143  *v |= (byte & 0x7F) << shift;
144  shift += 7;
145  DCHECK_LE(++num_bytes, MAX_VLQ_BYTE_LEN);
146  } while ((byte & 0x80) != 0);
147  return true;
148 }
149 
150 }
151 
152 #endif
bool GetAligned(int num_bytes, T *v)
bool PutValue(uint64_t v, int num_bits)
uint8_t * GetNextBytePtr(int num_bytes=1)
bool PutAligned(T v, int num_bytes)
static uint64_t TrailingBits(uint64_t v, int num_bits)
Returns the 'num_bits' least-significant bits of 'v'.
Definition: bit-util.h:125
bool GetVlqInt(int32_t *v)
void Flush(bool align=false)
static int Ceil(int value, int divisor)
Returns the ceil of value/divisor.
Definition: bit-util.h:32
#define UNLIKELY(expr)
Definition: compiler-util.h:33
#define LIKELY(expr)
Definition: compiler-util.h:32
static const int MAX_VLQ_BYTE_LEN
Maximum byte length of a vlq encoded int.
bool GetValue(int num_bits, T *v)