Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
bit-stream-utils.8byte.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_EXPERIMENTS_BIT_STREAM_UTILS_8BYTE_INLINE_H
17 #define IMPALA_EXPERIMENTS_BIT_STREAM_UTILS_8BYTE_INLINE_H
18 
20 
21 namespace impala {
22 
23 inline bool BitWriter_8byte::PutValue(uint64_t v, int num_bits) {
24  DCHECK_LE(num_bits, 64);
25  DCHECK(num_bits == 64 || v >> num_bits == 0)
26  << "v = " << v << ", num_bits = " << num_bits;
27 
28  if (UNLIKELY(offset_ * 8 + bit_offset_ > max_bytes_ * 8 - num_bits)) return false;
29 
30  buffer_[offset_] |= v << bit_offset_;
31  bit_offset_ += num_bits;
32  if (bit_offset_ >= 64) {
33  ++offset_;
34  bit_offset_ -= 64;
35  if (UNLIKELY(bit_offset_ > 0)) {
36  // Write out bits of v that crossed into new byte offset
37  // We cannot perform v >> num_bits (i.e. when bit_offset_ is 0) because v >> 64 != 0
38  buffer_[offset_] = v >> (num_bits - bit_offset_);
39  }
40  }
41  DCHECK_LT(bit_offset_, 64);
42  return true;
43 }
44 
45 inline uint8_t* BitWriter_8byte::GetNextBytePtr(int num_bytes) {
46  if (UNLIKELY(bytes_written() + num_bytes > max_bytes_)) return NULL;
47 
48  // Advance to next aligned byte if necessary
49  if (UNLIKELY(bit_offset_ > 56)) {
50  ++offset_;
51  bit_offset_ = 0;
52  } else {
54  }
55 
56  DCHECK_EQ(bit_offset_ % 8, 0);
57  uint8_t* ptr = reinterpret_cast<uint8_t*>(buffer_ + offset_) + bit_offset_ / 8;
58  bit_offset_ += num_bytes * 8;
59  offset_ += bit_offset_ / 64;
60  bit_offset_ %= 64;
61  return ptr;
62 }
63 
64 template<typename T>
65 inline bool BitWriter_8byte::PutAligned(T val, int num_bits) {
66  // Align to byte boundary
67  uint8_t* byte_ptr = GetNextBytePtr(0);
68  bool result = PutValue(val, num_bits);
69  if (!result) return false;
70  // Pad to next byte boundary
71  byte_ptr = GetNextBytePtr(0);
72  DCHECK(byte_ptr != NULL);
73  return true;
74 }
75 
76 inline bool BitWriter_8byte::PutVlqInt(int32_t v) {
77  bool result = true;
78  while ((v & 0xFFFFFF80) != 0L) {
79  result &= PutAligned<uint8_t>((v & 0x7F) | 0x80, 8);
80  v >>= 7;
81  }
82  result &= PutAligned<uint8_t>(v & 0x7F, 8);
83  return result;
84 }
85 
86 template<typename T>
87 inline bool BitReader_8byte::GetValue(int num_bits, T* v) {
88  int size = sizeof(T) * 8;
89  DCHECK_LE(num_bits, size);
90  if (UNLIKELY(offset_ * 8 + bit_offset_ > max_bytes_ * 8 - num_bits)) return false;
91 
93  bit_offset_ += num_bits;
94  if (bit_offset_ >= 64) {
95  ++offset_;
96  bit_offset_ -= 64;
97  // Read bits of v that crossed into new byte offset
99  buffer_[offset_], bit_offset_) << (num_bits - bit_offset_);
100  }
101  DCHECK_LT(bit_offset_, 64);
102  return true;
103 }
104 
105 template<typename T>
106 inline bool BitReader_8byte::GetAligned(int num_bits, T* v) {
107  Align();
108  if (UNLIKELY(bytes_left() < BitUtil::Ceil(num_bits, 8))) return false;
109  DCHECK_EQ(bit_offset_ % 8, 0);
110  bool result = GetValue(num_bits, v);
111  DCHECK(result);
112  Align();
113  return true;
114 }
115 
116 inline bool BitReader_8byte::GetVlqInt(int32_t* v) {
117  *v = 0;
118  int shift = 0;
119  int num_bytes = 0;
120  uint8_t byte = 0;
121  do {
122  if (!GetAligned<uint8_t>(8, &byte)) return false;
123  *v |= (byte & 0x7F) << shift;
124  shift += 7;
125  DCHECK_LE(++num_bytes, MAX_VLQ_BYTE_LEN);
126  } while ((byte & 0x80) != 0);
127  return true;
128 }
129 
130 inline void BitReader_8byte::Align() {
131  if (UNLIKELY(bit_offset_ > 56)) {
132  ++offset_;
133  bit_offset_ = 0;
134  DCHECK_LE(offset_, max_bytes_);
135  } else {
137  }
138 }
139 
140 }
141 
142 #endif
void Align()
Advances offset_ and/or bit_offset_ to next byte boundary in buffer_.
bool GetValue(int num_bits, T *v)
static uint64_t TrailingBits(uint64_t v, int num_bits)
Returns the 'num_bits' least-significant bits of 'v'.
Definition: bit-util.h:125
static uint32_t RoundUpNumBytes(uint32_t bits)
Definition: bit-util.h:77
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
static const int MAX_VLQ_BYTE_LEN
Maximum byte length of a vlq encoded int.
bool GetAligned(int num_bits, T *v)
uint8_t * GetNextBytePtr(int num_bytes=1)
bool PutAligned(T v, int num_bits)
Writes v to the next aligned byte.
bool PutValue(uint64_t v, int num_bits)