diff --git a/CHANGES b/CHANGES index 78b8eae17aeae7d1218a1f60874ba57df88ec82a..db465b01007f5e8b668ca0437d2cfaf89decce78 100644 --- a/CHANGES +++ b/CHANGES @@ -96,6 +96,12 @@ o Web.Sass Bug fixes --------- +o ADT.CritBit + + - Due to an off-by-one error the last limb of bignums was never compared. + This resulted (sometimes) in unequal bignums comparing equal inside of + the tree. + o Compiler - Improved variant robustness. diff --git a/src/post_modules/CritBit/critbit/key_bignum.h b/src/post_modules/CritBit/critbit/key_bignum.h index 5775ce5f247e1aa78283d6df8ddb407979a658f8..410675878b5edb8f118c631d05141b0840c10168 100644 --- a/src/post_modules/CritBit/critbit/key_bignum.h +++ b/src/post_modules/CritBit/critbit/key_bignum.h @@ -19,11 +19,13 @@ typedef mp_limb_t CB_NAME(char); #define cb_char CB_NAME(char) static CB_INLINE unsigned INT32 gclz(mp_limb_t a) { - if (sizeof(mp_limb_t) == 8) { - return clz64((unsigned INT64)a); - } else { - return clz32((unsigned INT32)a); - } +#if GMP_NUMB_BITS == 64 + return clz64((unsigned INT64)a); +#elif GMP_NUMB_BITS == 32 + return clz32((unsigned INT32)a); +#else +#error Only supports limb sizes of 32 or 64 bits. +#endif } #define O2G(o) ((MP_INT*)(o->storage)) @@ -46,11 +48,9 @@ static CB_INLINE mp_limb_t CB_GET_CHAR(cb_string s, ptrdiff_t n) { MP_INT * i = O2G(s); n += abs(i->_mp_size); - if (n > 0) { - //fprintf(stderr, ">> %lld %lld\n", n, i->_mp_d[abs(n)]); - return i->_mp_d[abs(i->_mp_size)-n]; + if (n >= 0) { + return i->_mp_d[abs(i->_mp_size) - 1 - n]; } else { - //fprintf(stderr, "�� %lld %lld\n", n, i->_mp_d[abs(n)]); return 0; } } diff --git a/src/post_modules/CritBit/testsuite.in b/src/post_modules/CritBit/testsuite.in index ce50314ec827c802649279613bd852fc93379c75..1d2a9dddac0399277faa95989f69b85c2c31a55a 100644 --- a/src/post_modules/CritBit/testsuite.in +++ b/src/post_modules/CritBit/testsuite.in @@ -200,6 +200,6 @@ test_tree(ADT.CritBit.IPv4Tree, [[mkmapping(map(enumerate(100)+enumerate(1000, - }), enumerate(2100))]], ADT.CritBit.sort_ipv4) test_tree(ADT.CritBit.FloatTree, [[mkmapping((array(float))(enumerate(100)+enumerate(1000, -19, 666)+enumerate(1000, Int.NATIVE_MAX/600, Int.NATIVE_MIN)), enumerate(2100))]], sort) test_tree(ADT.CritBit.DateTree, [[mkmapping(map(enumerate(2000, time()/3000, 1), Function.curry(Calendar.Second)("unix")), enumerate(2000))]], sort) - +test_tree(ADT.CritBit.BigNumTree, [[mkmapping(enumerate(10000, 2*Int.NATIVE_MAX, Int.NATIVE_MAX+1), enumerate(10000))]], sort) END_MARKER diff --git a/src/post_modules/CritBit/tree_high.c b/src/post_modules/CritBit/tree_high.c index c87676d6406f48b0201672f40e20d24986525573..648c7a8efa3877ed5a8e038786bbf6da2a7f2162 100644 --- a/src/post_modules/CritBit/tree_high.c +++ b/src/post_modules/CritBit/tree_high.c @@ -25,9 +25,9 @@ static inline void cb_debug_print_key(struct string_builder * buf, cb_key key) { #ifdef CB_PRINT_CHAR CB_PRINT_CHAR(buf, key.str, i.chars); #else - string_builder_sprintf(buf, "(%d, %d) b: ", i.chars, CB_WIDTH(s)); + string_builder_sprintf(buf, "(%d, %d) b: ", i.chars, CB_WIDTH(key.str)); - for (i.bits = 0; i.bits < CB_WIDTH(s); i.bits++) { + for (i.bits = 0; i.bits < CB_WIDTH(key.str); i.bits++) { string_builder_sprintf(buf, "%d", CB_GET_BIT(key.str, i)); } string_builder_putchar(buf, ' '); @@ -53,7 +53,7 @@ static inline void cb_print_key(struct string_builder * buf, const cb_key key) { cb_size i; for (i.chars = 0; i.chars < key.len.chars; i.chars++) { - for (i.bits = 0; i.bits < CB_WIDTH(s); i.bits++) { + for (i.bits = 0; i.bits < CB_WIDTH(key.str); i.bits++) { string_builder_putchar(buf, CB_GET_BIT(key.str, i) ? '1' : '0'); } }