nirbhay(a)mariadb.com writes:
> revision-id: 101d7eb963816514362da8a98fc7db7135181910
> committer: Nirbhay Choubey
> timestamp: 2015-01-31 21:48:14 -0500
> message:
>
> MDEV-4987: Sort by domain_id when list of GTIDs are output
>
> Added logic to sort gtid list based on domain_id before
> populating them in string. Added a test case.
Thanks!
The patch looks ok to push after fixing / considering below in-line comments:
> diff --git a/mysql-test/suite/rpl/t/rpl_gtid_sort.test b/mysql-test/suite/rpl/t/rpl_gtid_sort.test
> new file mode 100644
> index 0000000..d3b8c6d
> --- /dev/null
> +++ b/mysql-test/suite/rpl/t/rpl_gtid_sort.test
> +--connection server_2
> +SHOW VARIABLES LIKE '%GTID%';
> +#SET GLOBAL gtid_slave_pos="";
This commented-out SET looks like some left-over, probably you meant to remove
it?
> diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
> index e5620ec..a0471f3 100644
> --- a/sql/rpl_gtid.cc
> +++ b/sql/rpl_gtid.cc
> @@ -247,11 +247,13 @@
> {
> my_hash_init(&hash, &my_charset_bin, 32, offsetof(element, domain_id),
> sizeof(uint32), NULL, rpl_slave_state_free_element, HASH_UNIQUE);
> + my_init_dynamic_array(>id_cache, sizeof(rpl_gtid), 8, 8, MYF(0));
The name 'cache' confused me slightly, as I think of a cache as something that
stores some state between invocations. But it is actually just a temporary
buffer used for sorting.
A suggestion for a better name could be 'gtid_sort_array'.
> rpl_slave_state::~rpl_slave_state()
> {
> + delete_dynamic(>id_cache);
> }
The other parts of rpl_slave_state are freed in rpl_slave_state::deinit(). I
think this is because there is a global variable of this class, and
destructors in global variables can cause various issues.
So better put this delete_dynamic() into deinit() as well (for consistency, if
nothing else).
> @@ -705,7 +707,13 @@ class Gtid_db_intact : public Table_check_intact
> return sub_id;
> }
>
> +/* A callback used in sorting of gtid list based on domain_id. */
> +static int rpl_gtid_cmp_cb(const void *id1, const void *id2)
> +{
> + return (((rpl_gtid *)id1)->domain_id - ((rpl_gtid *)id2)->domain_id);
> +}
I think this is wrong, you can get signed/unsigned integer overflow (eg. it
will consider 0xffffffff as being less than 0x00000000).
We might be able to do the subtraction in longlong with a cast (though that
would still be susceptible to overflow when converting to the int return
value, right?), but it's probably clearer to just do:
uint32 d1= ((rpl_gtid *)id1)->domain_id;
uint32 d2= ((rpl_gtid *)id2)->domain_id;
if (d1 < d2)
return -1;
else if (d1 > f2)
return 1;
else
return 0;
You should probably also modify the test case to have a domain id >
0x80000000, just to check.
Otherwise looks good, thanks!
- Kristian.