mirror of
https://github.com/MariaDB/server.git
synced 2025-02-23 05:43:08 +01:00

fts_doc_id_cmp(): Replaces several duplicated functions for comparing two doc_id_t*. On IA-32, AMD64, ARMv7, ARMv8, RISC-V this should make use of some conditional ALU instructions. On POWER there will be conditional jumps. Unlike the original functions, these will return the correct result even if the difference of the two doc_id does not fit in the int data type. We use static_assert() and offsetof() to check at compilation time that this function is compatible with the rbt_create() calls. fts_query_compare_rank(): As documented, return -1 and not 1 when the rank are equal and r1->doc_id < r2->doc_id. This will affect the result of ha_innobase::ft_read(). fts_ptr2_cmp(), fts_ptr1_ptr2_cmp(): These replace fts_trx_table_cmp(), fts_trx_table_id_cmp(). The fts_savepoint_t::tables will be sorted by dict_table_t* rather than dict_table_t::id. There was no correctness bug in the previous comparison predicates. We can avoid one level of unnecessary pointer dereferencing in this way. Actually, fts_savepoint_t is duplicating trx_t::mod_tables. MDEV-33401 was filed about removing it. The added unit test innodb_rbt-t covers both the previous buggy comparison predicate and the revised fts_doc_id_cmp(), using keys which led to finding the bug. Thanks to Shaohua Wang from Alibaba for providing the example and the revised comparison predicate. Reviewed by: Thirunarayanan Balathandayuthapani
82 lines
2.3 KiB
C++
82 lines
2.3 KiB
C++
#include "tap.h"
|
|
#include "ut0rbt.h"
|
|
|
|
const size_t alloc_max_retries= 0;
|
|
void os_thread_sleep(ulint) { abort(); }
|
|
void ut_dbg_assertion_failed(const char *, const char *, unsigned)
|
|
{ abort(); }
|
|
namespace ib { fatal_or_error::~fatal_or_error() { abort(); } }
|
|
#ifdef UNIV_PFS_MEMORY
|
|
PSI_memory_key mem_key_other, mem_key_std;
|
|
PSI_memory_key ut_new_get_key_by_file(uint32_t) { return mem_key_std; }
|
|
#endif
|
|
|
|
static const uint64_t doc_ids[]=
|
|
{
|
|
103571, 104018, 106821, 108647, 109352, 109379,
|
|
110325, 122868, 210682130, 231275441, 234172769, 366236849,
|
|
526467159, 1675241735, 1675243405, 1947751899, 1949940363, 2033691953,
|
|
2148227299, 2256289791, 2294223591, 2367501260, 2792700091, 2792701220,
|
|
2817121627, 2820680352, 2821165664, 3253312130, 3404918378, 3532599429,
|
|
3538712078, 3539373037, 3546479309, 3566641838, 3580209634, 3580871267,
|
|
3693930556, 3693932734, 3693932983, 3781949558, 3839877411, 3930968983
|
|
};
|
|
|
|
static int fts_doc_id_cmp(const void *p1, const void *p2)
|
|
{
|
|
uint64_t a= *static_cast<const uint64_t*>(p1),
|
|
b= *static_cast<const uint64_t*>(p2);
|
|
return b > a ? -1 : a > b;
|
|
}
|
|
|
|
|
|
static int fts_doc_id_buggy_cmp(const void *p1, const void *p2)
|
|
{
|
|
return int(*static_cast<const uint64_t*>(p1) -
|
|
*static_cast<const uint64_t*>(p2));
|
|
}
|
|
|
|
typedef int (*comparator) (const void*, const void*);
|
|
|
|
static void rbt_populate(ib_rbt_t *rbt)
|
|
{
|
|
ib_rbt_bound_t parent;
|
|
for (const uint64_t &doc_id : doc_ids)
|
|
{
|
|
if (rbt_search(rbt, &parent, &doc_id))
|
|
rbt_add_node(rbt, &parent, &doc_id);
|
|
}
|
|
}
|
|
|
|
static void rbt_populate2(ib_rbt_t *rbt)
|
|
{
|
|
for (const uint64_t &doc_id : doc_ids)
|
|
rbt_insert(rbt, &doc_id, &doc_id);
|
|
}
|
|
|
|
static bool rbt_search_all(ib_rbt_t *rbt)
|
|
{
|
|
ib_rbt_bound_t parent;
|
|
for (const uint64_t &doc_id : doc_ids)
|
|
if (rbt_search(rbt, &parent, &doc_id))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
static void rbt_test(comparator cmp, bool buggy)
|
|
{
|
|
ib_rbt_t *rbt= rbt_create(sizeof(uint64_t), cmp);
|
|
rbt_populate(rbt);
|
|
ok(rbt_search_all(rbt) != buggy, "search after populate");
|
|
rbt_free(rbt);
|
|
rbt= rbt_create(sizeof(uint64_t), cmp);
|
|
rbt_populate2(rbt);
|
|
ok(rbt_search_all(rbt) != buggy, "search after populate2");
|
|
rbt_free(rbt);
|
|
}
|
|
|
|
int main ()
|
|
{
|
|
rbt_test(fts_doc_id_buggy_cmp, true);
|
|
rbt_test(fts_doc_id_cmp, false);
|
|
}
|