@@ -41,7 +41,7 @@ Hll8Array<A>::Hll8Array(const HllArray<A>& other):
4141 this ->oooFlag_ = other.isOutOfOrderFlag ();
4242 uint32_t num_zeros = 1 << this ->lgConfigK_ ;
4343
44- for (const auto & coupon : other) { // all = false, so skip empty values
44+ for (const auto coupon : other) { // all = false, so skip empty values
4545 num_zeros--;
4646 internalCouponUpdate (coupon); // updates KxQ registers
4747 }
@@ -114,37 +114,78 @@ void Hll8Array<A>::mergeList(const CouponList<A>& src) {
114114template <typename A>
115115void Hll8Array<A>::mergeHll(const HllArray<A>& src) {
116116 // at this point src_k >= dst_k
117- const uint32_t dst_mask = (1 << this ->getLgConfigK ()) - 1 ;
118- // special treatment below to optimize performance
119- if (src.getTgtHllType () == target_hll_type::HLL_8 ) {
120- uint32_t i = 0 ;
121- for (const auto value: src.getHllArray ()) {
122- processValue (i++, dst_mask, value);
117+ // we can optimize further when the k values are equal
118+ if (this ->getLgConfigK () == src.getLgConfigK ()) {
119+ if (src.getTgtHllType () == target_hll_type::HLL_8 ) {
120+ uint32_t i = 0 ;
121+ for (const auto value: src.getHllArray ()) {
122+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], value);
123+ ++i;
124+ }
125+ } else if (src.getTgtHllType () == target_hll_type::HLL_6 ) {
126+ const uint32_t src_k = 1 << src.getLgConfigK ();
127+ uint32_t i = 0 ;
128+ const uint8_t * ptr = src.getHllArray ().data ();
129+ while (i < src_k) {
130+ uint8_t value = *ptr & 0x3f ;
131+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], value);
132+ ++i;
133+ value = *ptr++ >> 6 ;
134+ value |= (*ptr & 0x0f ) << 2 ;
135+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], value);
136+ ++i;
137+ value = *ptr++ >> 4 ;
138+ value |= (*ptr & 3 ) << 4 ;
139+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], value);
140+ ++i;
141+ value = *ptr++ >> 2 ;
142+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], value);
143+ ++i;
144+ }
145+ } else { // HLL_4
146+ const auto & src4 = static_cast <const Hll4Array<A>&>(src);
147+ uint32_t i = 0 ;
148+ for (const auto byte: src.getHllArray ()) {
149+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], src4.adjustRawValue (i, byte & hll_constants::loNibbleMask));
150+ ++i;
151+ this ->hllByteArr_ [i] = std::max (this ->hllByteArr_ [i], src4.adjustRawValue (i, byte >> 4 ));
152+ ++i;
153+ }
123154 }
124- } else if (src.getTgtHllType () == target_hll_type::HLL_6 ) {
125- const uint32_t src_k = 1 << src.getLgConfigK ();
126- uint32_t i = 0 ;
127- const uint8_t * ptr = src.getHllArray ().data ();
128- while (i < src_k) {
129- uint8_t value = *ptr & 0x3f ;
130- processValue (i++, dst_mask, value);
131- value = *ptr++ >> 6 ;
132- value |= (*ptr & 0x0f ) << 2 ;
133- processValue (i++, dst_mask, value);
134- value = *ptr++ >> 4 ;
135- value |= (*ptr & 3 ) << 4 ;
136- processValue (i++, dst_mask, value);
137- value = *ptr++ >> 2 ;
138- processValue (i++, dst_mask, value);
139- }
140- } else { // HLL_4
141- const auto & src4 = static_cast <const Hll4Array<A>&>(src);
142- uint32_t i = 0 ;
143- for (const auto byte: src.getHllArray ()) {
144- processValue (i, dst_mask, src4.adjustRawValue (i, byte & hll_constants::loNibbleMask));
145- ++i;
146- processValue (i, dst_mask, src4.adjustRawValue (i, byte >> 4 ));
147- ++i;
155+ } else {
156+ // src_k > dst_k
157+ const uint32_t dst_mask = (1 << this ->getLgConfigK ()) - 1 ;
158+ // special treatment below to optimize performance
159+ if (src.getTgtHllType () == target_hll_type::HLL_8 ) {
160+ uint32_t i = 0 ;
161+ for (const auto value: src.getHllArray ()) {
162+ processValue (i++, dst_mask, value);
163+ }
164+ } else if (src.getTgtHllType () == target_hll_type::HLL_6 ) {
165+ const uint32_t src_k = 1 << src.getLgConfigK ();
166+ uint32_t i = 0 ;
167+ const uint8_t * ptr = src.getHllArray ().data ();
168+ while (i < src_k) {
169+ uint8_t value = *ptr & 0x3f ;
170+ processValue (i++, dst_mask, value);
171+ value = *ptr++ >> 6 ;
172+ value |= (*ptr & 0x0f ) << 2 ;
173+ processValue (i++, dst_mask, value);
174+ value = *ptr++ >> 4 ;
175+ value |= (*ptr & 3 ) << 4 ;
176+ processValue (i++, dst_mask, value);
177+ value = *ptr++ >> 2 ;
178+ processValue (i++, dst_mask, value);
179+ }
180+ } else { // HLL_4
181+ const auto & src4 = static_cast <const Hll4Array<A>&>(src);
182+ uint32_t i = 0 ;
183+ for (const auto byte: src.getHllArray ()) {
184+ processValue (i, dst_mask, src4.adjustRawValue (i, byte & hll_constants::loNibbleMask));
185+ ++i;
186+ processValue (i, dst_mask, src4.adjustRawValue (i, byte >> 4 ));
187+ ++i;
188+ }
148189 }
149190 }
150191 this ->setRebuildKxqCurminFlag (true );
0 commit comments