MCPcopy Create free account
hub / github.com/apache/impala / PackUnpack

Function PackUnpack

be/src/util/bit-packing-test.cc:67–119  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

65/// by 1 byte from a 64-byte aligned address.
66template <typename UINT_T>
67void PackUnpack(const UINT_T* in, int num_in_values, int bit_width, bool aligned) {
68 LOG(INFO) << "num_in_values = " << num_in_values << " bit_width = " << bit_width
69 << " aligned = " << aligned;
70
71 // Mask out higher bits so that the values to pack are in range.
72 const UINT_T mask = ComputeMask<UINT_T>(bit_width);
73 const int misalignment = aligned ? 0 : 1;
74
75 const int bytes_required = BitUtil::RoundUpNumBytes(bit_width * num_in_values);
76 AlignedAllocation storage(bytes_required + misalignment);
77 uint8_t* packed = storage.data() + misalignment;
78
79 BitWriter writer(packed, bytes_required);
80 if (bit_width > 0) {
81 for (int i = 0; i < num_in_values; ++i) {
82 ASSERT_TRUE(writer.PutValue(in[i] & mask, bit_width));
83 }
84 }
85 writer.Flush();
86 LOG(INFO) << "Wrote " << writer.bytes_written() << " bytes.";
87
88 // Test unpacking all the values. Trying to unpack extra values should have the same
89 // result because the input buffer size 'num_in_values' limits the number of values to
90 // return.
91 for (const int num_to_unpack : {num_in_values, num_in_values + 1, num_in_values + 77}) {
92 LOG(INFO) << "Unpacking " << num_to_unpack;
93 // Size buffer exactly so that ASAN can detect reads/writes that overrun the buffer.
94 AlignedAllocation out_storage(num_to_unpack * sizeof(UINT_T) + misalignment);
95 UINT_T* out = reinterpret_cast<UINT_T*>(out_storage.data() + misalignment);
96 const auto result = BitPacking::UnpackValues<UINT_T>(
97 bit_width, packed, writer.bytes_written(), num_to_unpack, out);
98 ASSERT_EQ(packed + writer.bytes_written(), result.first)
99 << "Unpacked different # of bytes from the # written";
100 if (bit_width == 0) {
101 // If no bits, we can get back as many as we ask for.
102 ASSERT_EQ(num_to_unpack, result.second) << "Unpacked wrong # of values";
103 } else if (bit_width < CHAR_BIT) {
104 // We may get back some garbage values that we didn't actually pack if we
105 // didn't use all of the trailing byte.
106 const int max_packed_values = writer.bytes_written() * CHAR_BIT / bit_width;
107 ASSERT_EQ(min(num_to_unpack, max_packed_values), result.second)
108 << "Unpacked wrong # of values";
109 } else {
110 ASSERT_EQ(num_in_values, result.second) << "Unpacked wrong # of values";
111 }
112
113 for (int i = 0; i < num_in_values; ++i) {
114 EXPECT_EQ(in[i] & mask, out[i]) << "Didn't get back input value " << i << "."
115 << " Bit width: " << bit_width << ".";
116 }
117 }
118 UnpackSubset<UINT_T>(in, packed, num_in_values, bit_width, aligned);
119}
120
121template <typename UINT_T>
122void UnpackSubset(const UINT_T* in, const uint8_t* packed, int num_in_values,

Callers

nothing calls this directly

Calls 5

minFunction · 0.85
dataMethod · 0.45
PutValueMethod · 0.45
FlushMethod · 0.45
bytes_writtenMethod · 0.45

Tested by

no test coverage detected