24 #include <ndb_global.h> 
   48 prepare_master_or_slave(
Ndb &myNdb,
 
   56 run_master_update(
struct Xxx &xxx, 
struct XxxR &xxxr);
 
   58 run_slave_wait(
struct Xxx &xxx, 
struct XxxR &xxxr);
 
   60 #define PRINT_ERROR(code,msg) \ 
   61   g_err << "Error in " << __FILE__ << ", line: " << __LINE__ \ 
   62             << ", code: " << code \ 
   63             << ", msg: " << msg << ".\n" 
   64 #define APIERROR(error) { \ 
   65   PRINT_ERROR((error).code, (error).message); \ 
   68 int main(
int argc, 
char** argv)
 
   72     ndbout << 
"Arguments are <connect_string cluster 1> <connect_string cluster 2> <database> <table name> <primary key> <value of primary key> <attribute to update>.\n";
 
   78     const char *opt_connectstring1 = argv[1];
 
   79     const char *opt_connectstring2 = argv[2];
 
   80     const char *opt_db             = argv[3];
 
   81     const char *opt_table          = argv[4];
 
   82     const char *opt_pk             = argv[5];
 
   83     const Uint32 opt_pk_val        = atoi(argv[6]);
 
   84     const char *opt_col            = argv[7];
 
   93     if (cluster1_connection.connect(4 ,
 
   97       g_err << 
"Cluster 1 management server was not ready within 30 secs.\n";
 
  101     if (cluster1_connection.wait_until_ready(30,0) < 0)
 
  103       g_err << 
"Cluster 1 was not ready within 30 secs.\n";
 
  108     if (cluster2_connection.connect(4 ,
 
  112       g_err << 
"Cluster 2 management server was not ready within 30 secs.\n";
 
  116     if (cluster2_connection.wait_until_ready(30,0) < 0)
 
  118       g_err << 
"Cluster 2 was not ready within 30 secs.\n";
 
  122     Ndb myNdb1(&cluster1_connection, opt_db);
 
  123     Ndb myNdb2(&cluster2_connection, opt_db);
 
  128     prepare_master_or_slave(myNdb1, opt_table, opt_pk, opt_pk_val, opt_col,
 
  130     prepare_master_or_slave(myNdb2, opt_table, opt_pk, opt_pk_val, opt_col,
 
  135       run_master_update(xxx1, xxxr);
 
  136       run_slave_wait(xxx2, xxxr);
 
  137       ndbout << 
"latency: " << xxxr.latency << endl;
 
  147 prepare_master_or_slave(
Ndb &myNdb,
 
  166     PRINT_ERROR(0, 
"Primary key column not of type unsigned");
 
  174     PRINT_ERROR(0, 
"Update column not of type unsigned");
 
  180   xxx.pk_col = myPkCol->getColumnNo();
 
  183   xxxr.pk_val = pk_val;
 
  188 static void run_master_update(
struct Xxx &xxx, 
struct XxxR &xxxr)
 
  205       op->
equal(xxx.pk_col, xxxr.pk_val);
 
  206       op->
getValue(xxx.col, (
char *)&val);
 
  217       op->
equal(xxx.pk_col, xxxr.pk_val);
 
  234         NdbSleep_MilliSleep(retry_sleep);
 
  240     APIERROR(this_error);
 
  243   gettimeofday(&xxxr.start_time, 0);
 
  246 static void run_slave_wait(
struct Xxx &xxx, 
struct XxxR &xxxr)
 
  248   struct timeval old_end_time = xxxr.start_time, end_time;
 
  264       op->
equal(xxx.pk_col, xxxr.pk_val);
 
  265       op->
getValue(xxx.col, (
char *)&val);
 
  270     gettimeofday(&end_time, 0);
 
  277       NdbSleep_MilliSleep(retry_sleep);
 
  278       old_end_time =  end_time;
 
  291         NdbSleep_MilliSleep(retry_sleep);
 
  297     APIERROR(this_error);
 
  300   Int64 elapsed_usec1 =
 
  301     ((Int64)end_time.tv_sec - (Int64)xxxr.start_time.tv_sec)*1000*1000 +
 
  302     ((Int64)end_time.tv_usec - (Int64)xxxr.start_time.tv_usec);
 
  303   Int64 elapsed_usec2 =
 
  304     ((Int64)end_time.tv_sec - (Int64)old_end_time.tv_sec)*1000*1000 +
 
  305     ((Int64)end_time.tv_usec - (Int64)old_end_time.tv_usec);
 
  307     ((elapsed_usec1 - elapsed_usec2/2)+999)/1000;