HLL_SET_REGISTER fixed.

There was an error in the first version of the macro.
Now the HLLSELFTEST test reports success.
This commit is contained in:
antirez 2014-03-28 13:56:04 +01:00
parent f22397dd7f
commit e73839e7d5

View File

@ -62,6 +62,7 @@
* We use macros to make sure the code is inlined since speed is critical * We use macros to make sure the code is inlined since speed is critical
* especially in order to compute the approximated cardinality in * especially in order to compute the approximated cardinality in
* HLLCOUNT where we need to access all the registers at once. * HLLCOUNT where we need to access all the registers at once.
* For the same reason we also want to avoid conditionals in this code path.
* *
* +--------+--------+--------+------// * +--------+--------+--------+------//
* |00000011|11112222|22333333|444444 * |00000011|11112222|22333333|444444
@ -106,21 +107,26 @@
* we need to bitwise-OR the new bits. * we need to bitwise-OR the new bits.
* *
* This time let's try with 'pos' = 1, so our first byte at 'b' is 0, * This time let's try with 'pos' = 1, so our first byte at 'b' is 0,
* "ls" is 6, and "rs" is 2. *
* "ls" is 6, and you may notice it is actually the position of the first
* bit inside the byte. "rs" is 8-ls = 2
* *
* +--------+ * +--------+
* |00000011| <- Our initial byte at "b" * |00000011| <- Our initial byte at "b"
* +--------+ * +--------+
* *
* We store at "mask" the value 255, consisting of a byte with all bits * To create a AND-mask to clear the bits about this position, we just
* set to 1. We left-shift it of "rs" bits to the left. * initialize the mask with 2^6-1, right shift it of "ls" bits, and invert
* it.
* *
* +--------+ * +--------+
* |11111100| <- "mask" after the left-shift of 'rs' bits. * |11111100| <- "mask" starts at 2^6-1
* |00000011| <- "mask" after right shift of "ls" bits.
* |11111100| <- "mask" after invert.
* +--------+ * +--------+
* *
* Now we can bitwise-AND the byte at "b" with the mask, and bitwise-OR * Now we can bitwise-AND the byte at "b" with the mask, and bitwise-OR
* it with "val" right-shifted of "ls" to set the new bits. * it with "val" right-shifted of "ls" bits to set the new bits.
* *
* Now let's focus on the next byte b+1: * Now let's focus on the next byte b+1:
* *
@ -128,13 +134,13 @@
* |11112222| <- byte at b+1 * |11112222| <- byte at b+1
* +--------+ * +--------+
* *
* To build the AND mask for the next byte b+1 we left shift it by "rs" * To build the AND mask we start again with the 2^6-1 value, left shift
* amount of bits a byte with value 2^6-1. Later we negate (bitwise-not) it. * it by "rs" bits, and invert it.
* *
* +--------+ * +--------+
* |11111100| <- "filter" set at 2&6-1 * |11111100| <- "mask" set at 2&6-1
* |11110000| <- "filter" after the left shift of "rs" bits. * |11110000| <- "mask" after the left shift of "rs" bits.
* |00001111| <- "filter" after bitwise not. * |00001111| <- "mask" after bitwise not.
* +--------+ * +--------+
* *
* Now we can mask it with b+1 to clear the old bits, and bitwise-OR * Now we can mask it with b+1 to clear the old bits, and bitwise-OR
@ -165,10 +171,9 @@
int _byte = regnum*REDIS_HLL_BITS/8; \ int _byte = regnum*REDIS_HLL_BITS/8; \
int _leftshift = regnum*REDIS_HLL_BITS&7; \ int _leftshift = regnum*REDIS_HLL_BITS&7; \
int _rightshift = 8 - _leftshift; \ int _rightshift = 8 - _leftshift; \
uint8_t m1 = 255, m2 = REDIS_HLL_REGISTER_MAX; \ _p[_byte] &= ~(REDIS_HLL_REGISTER_MAX >> _leftshift); \
_p[_byte] &= m1 << _rightshift; \
_p[_byte] |= val >> _leftshift; \ _p[_byte] |= val >> _leftshift; \
_p[_byte+1] &= ~(m2 << _rightshift); \ _p[_byte+1] &= ~(REDIS_HLL_REGISTER_MAX << _rightshift); \
_p[_byte+1] |= val << _rightshift; \ _p[_byte+1] |= val << _rightshift; \
} while(0) } while(0)