section.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. /*
  2. * Copyright [2021] JD.com, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef __CH_SECTION_H__
  17. #define __CH_SECTION_H__
  18. #include "mem_check.h"
  19. #include <string.h>
  20. #include <math.h>
  21. #include <errno.h>
  22. #include <new>
  23. #include "value.h"
  24. #include "protocol.h"
  25. #include "log/log.h"
  26. #define MAX_STATIC_SECTION 20
  27. /*
  28. * tag: a pair of id:value, the value type if predefined
  29. * section: a set of id:value
  30. */
  31. struct SectionDefinition {
  32. uint8_t sectionId;
  33. uint8_t maxTags;
  34. uint8_t tagType[256];
  35. uint8_t tag_type(uint8_t i) const
  36. {
  37. return tagType[i];
  38. };
  39. int max_tags(void) const
  40. {
  41. return maxTags;
  42. }
  43. int section_id(void) const
  44. {
  45. return sectionId;
  46. }
  47. };
  48. class SimpleSection {
  49. private:
  50. const SectionDefinition *definition;
  51. uint8_t numTags;
  52. #if MAX_STATIC_SECTION
  53. uint8_t fieldMask[(MAX_STATIC_SECTION + 7) / 8];
  54. #else
  55. uint8_t fieldMask[32];
  56. #endif
  57. public:
  58. #if MAX_STATIC_SECTION
  59. DTCValue tagValue[MAX_STATIC_SECTION];
  60. #else
  61. DTCValue *tagValue;
  62. #endif
  63. SimpleSection(const SectionDefinition &d) : definition(&d), numTags(0)
  64. {
  65. #if MAX_STATIC_SECTION
  66. for (int i = 0; i < d.max_tags(); i++)
  67. tagValue[i].Set(NULL, 0);
  68. #else
  69. tagValue = (DTCValue *)calloc(d.max_tags(), sizeof(DTCValue));
  70. if (tagValue == NULL)
  71. throw std::bad_alloc();
  72. #endif
  73. FIELD_ZERO(fieldMask);
  74. }
  75. virtual ~SimpleSection()
  76. {
  77. #if !MAX_STATIC_SECTION
  78. FREE_IF(tagValue);
  79. #endif
  80. }
  81. SimpleSection(const SimpleSection &orig)
  82. {
  83. #if !MAX_STATIC_SECTION
  84. tagValue = (DTCValue *)malloc(orig.definition->max_tags(),
  85. sizeof(DTCValue));
  86. if (tagValue == NULL)
  87. throw std::bad_alloc();
  88. #endif
  89. Copy(orig);
  90. }
  91. void Copy(const SimpleSection &orig)
  92. {
  93. for (int i = 0; i < orig.definition->max_tags(); i++)
  94. tagValue[i] = orig.tagValue[i];
  95. memcpy(fieldMask, orig.fieldMask, sizeof(fieldMask));
  96. definition = orig.definition;
  97. numTags = orig.numTags;
  98. }
  99. inline virtual void Clean()
  100. {
  101. memset(tagValue, 0, sizeof(DTCValue) * definition->max_tags());
  102. FIELD_ZERO(fieldMask);
  103. numTags = 0;
  104. }
  105. int max_tags(void) const
  106. {
  107. return definition->max_tags();
  108. }
  109. int num_tags(void) const
  110. {
  111. return numTags;
  112. }
  113. int section_id(void) const
  114. {
  115. return definition->section_id();
  116. }
  117. uint8_t tag_type(uint8_t id) const
  118. {
  119. return definition->tag_type(id);
  120. }
  121. int tag_present(uint8_t id) const
  122. {
  123. return id >= MAX_STATIC_SECTION ? 0 :
  124. FIELD_ISSET(id, fieldMask);
  125. }
  126. void set_tag(uint8_t id, const DTCValue &val)
  127. {
  128. if (tag_type(id) != DField::None) {
  129. tagValue[id] = val;
  130. if (!FIELD_ISSET(id, fieldMask)) {
  131. numTags++;
  132. FIELD_SET(id, fieldMask);
  133. }
  134. }
  135. }
  136. /* no check of dumplicate tag */
  137. void SetTagMask(uint8_t id)
  138. {
  139. numTags++;
  140. FIELD_SET(id, fieldMask);
  141. }
  142. void set_tag(uint8_t id, int64_t val)
  143. {
  144. set_tag(id, DTCValue::Make(val));
  145. }
  146. void set_tag(uint8_t id, uint64_t val)
  147. {
  148. set_tag(id, DTCValue::Make(val));
  149. }
  150. void set_tag(uint8_t id, int32_t val)
  151. {
  152. if (tag_type(id) == DField::Signed)
  153. set_tag(id, DTCValue::Make(val));
  154. else if (tag_type(id) == DField::Unsigned) {
  155. if (val < 0)
  156. val = 0;
  157. set_tag(id, DTCValue::Make((uint64_t)val));
  158. }
  159. }
  160. void set_tag(uint8_t id, uint32_t val)
  161. {
  162. //fix Unsigned to Signed
  163. if (tag_type(id) == DField::Signed)
  164. set_tag(id, DTCValue::Make((int64_t)val));
  165. else if (tag_type(id) == DField::Unsigned)
  166. set_tag(id, DTCValue::Make(val));
  167. }
  168. void set_tag(uint8_t id, double val)
  169. {
  170. if (tag_type(id) == DField::Float)
  171. set_tag(id, DTCValue::Make(val));
  172. }
  173. void set_tag(uint8_t id, const char *val, int len)
  174. {
  175. if (tag_type(id) == DField::String ||
  176. tag_type(id) == DField::Binary)
  177. set_tag(id, DTCValue::Make(val, len));
  178. }
  179. void set_tag(uint8_t id, const char *val)
  180. {
  181. if (tag_type(id) == DField::String ||
  182. tag_type(id) == DField::Binary)
  183. set_tag(id, DTCValue::Make(val));
  184. }
  185. const DTCValue *get_tag(uint8_t id) const
  186. {
  187. return tag_present(id) ? &tagValue[id] : NULL;
  188. }
  189. /* no check */
  190. DTCValue *get_this_tag(uint8_t id)
  191. {
  192. return &tagValue[id];
  193. }
  194. const DTCValue *key(void) const
  195. {
  196. return tag_present(0) ? &tagValue[0] : NULL;
  197. }
  198. void set_key(const DTCValue &k)
  199. {
  200. set_tag(0, k);
  201. }
  202. };
  203. extern const SectionDefinition versionInfoDefinition;
  204. extern const SectionDefinition requestInfoDefinition;
  205. extern const SectionDefinition resultInfoDefinition;
  206. class DTCVersionInfo : public SimpleSection {
  207. public:
  208. DTCVersionInfo() : SimpleSection(versionInfoDefinition)
  209. {
  210. }
  211. ~DTCVersionInfo()
  212. {
  213. }
  214. DTCVersionInfo(const DTCVersionInfo &orig) : SimpleSection(orig)
  215. {
  216. }
  217. const DTCBinary &table_name(void) const
  218. {
  219. return tagValue[1].str;
  220. }
  221. void set_table_name(const char *n)
  222. {
  223. set_tag(1, n);
  224. }
  225. const DTCBinary &table_hash(void) const
  226. {
  227. return tagValue[4].str;
  228. }
  229. void set_table_hash(const char *n)
  230. {
  231. set_tag(4, n, 16);
  232. }
  233. const DTCBinary &data_table_hash(void) const
  234. {
  235. return tagValue[2].str;
  236. }
  237. void set_data_table_hash(const char *n)
  238. {
  239. set_tag(2, n, 16);
  240. }
  241. const DTCBinary &CTLibVer(void) const
  242. {
  243. return tagValue[6].str;
  244. }
  245. const int CTLibIntVer(void) const
  246. {
  247. int major = 3; //, minor=0, micro=0;
  248. /* 3.x系列的批量拆包之后没有version信息 */
  249. if (NULL == CTLibVer().ptr) {
  250. log4cplus_debug("multi job have no version info");
  251. return major;
  252. }
  253. char buf = CTLibVer().ptr[7];
  254. if (buf >= '1' && buf <= '9') {
  255. major = buf - '0';
  256. log4cplus_debug(
  257. "client major version:%d,version string:%s",
  258. major, CTLibVer().ptr);
  259. return major;
  260. } else {
  261. log4cplus_debug("unknown client api version: %s",
  262. CTLibVer().ptr);
  263. return major;
  264. }
  265. }
  266. int ReConnect(void) const
  267. {
  268. return tagValue[19].u64;
  269. }
  270. int key_type(void) const
  271. {
  272. return tagValue[9].u64;
  273. }
  274. void set_key_type(int n)
  275. {
  276. set_tag(9, n);
  277. }
  278. #if MAX_STATIC_SECTION >= 1 && MAX_STATIC_SECTION < 10
  279. #error MAX_STATIC_SECTION must >= 10
  280. #endif
  281. const uint64_t serial_nr(void) const
  282. {
  283. return tagValue[3].u64;
  284. }
  285. void set_serial_nr(uint64_t u)
  286. {
  287. set_tag(3, u);
  288. }
  289. const int keep_alive_timeout(void) const
  290. {
  291. return (int)tagValue[8].u64;
  292. }
  293. void set_keep_alive_timeout(uint32_t u)
  294. {
  295. set_tag(8, u);
  296. }
  297. void set_hot_backup_id(uint64_t u)
  298. {
  299. set_tag(14, u);
  300. }
  301. uint64_t hot_backup_id() const
  302. {
  303. return tagValue[14].u64;
  304. }
  305. void set_master_hb_timestamp(int64_t t)
  306. {
  307. set_tag(15, t);
  308. }
  309. int64_t master_hb_timestamp(void) const
  310. {
  311. return tagValue[15].s64;
  312. }
  313. void set_slave_hb_timestamp(int64_t t)
  314. {
  315. set_tag(16, t);
  316. }
  317. int64_t slave_hb_timestamp(void) const
  318. {
  319. return tagValue[16].s64;
  320. }
  321. uint64_t get_agent_client_id() const
  322. {
  323. return tagValue[17].u64;
  324. }
  325. void set_agent_client_id(uint64_t id)
  326. {
  327. set_tag(17, id);
  328. }
  329. void set_access_key(const char *token)
  330. {
  331. set_tag(18, token);
  332. }
  333. const DTCBinary &access_key(void) const
  334. {
  335. return tagValue[18].str;
  336. }
  337. };
  338. class DTCRequestInfo : public SimpleSection {
  339. public:
  340. DTCRequestInfo() : SimpleSection(requestInfoDefinition)
  341. {
  342. }
  343. ~DTCRequestInfo()
  344. {
  345. }
  346. DTCRequestInfo(const DTCRequestInfo &orig) : SimpleSection(orig)
  347. {
  348. }
  349. uint64_t get_expire_time(int version) const
  350. {
  351. /* server内部全部按照ms单位来处理超时 */
  352. if (version >= 3)
  353. /* 3.x 系列客户端发送的超时时间单位:us */
  354. return tagValue[1].u64 >> 10;
  355. else
  356. /* 2.x 系列客户端发送的超时时间单位: ms */
  357. return tagValue[1].u64;
  358. }
  359. void set_timeout(uint32_t n)
  360. {
  361. set_tag(1, (uint64_t)n << 10);
  362. }
  363. uint32_t limit_start(void) const
  364. {
  365. return tagValue[2].u64;
  366. }
  367. uint32_t limit_count(void) const
  368. {
  369. return tagValue[3].u64;
  370. }
  371. void set_limit_start(uint32_t n)
  372. {
  373. set_tag(2, (uint64_t)n);
  374. }
  375. void set_limit_count(uint32_t n)
  376. {
  377. set_tag(3, (uint64_t)n);
  378. }
  379. uint32_t admin_code() const
  380. {
  381. return tagValue[7].u64;
  382. }
  383. void set_admin_code(uint32_t code)
  384. {
  385. set_tag(7, (uint64_t)code);
  386. }
  387. };
  388. class DTCResultInfo : public SimpleSection {
  389. private:
  390. char *szErrMsg;
  391. char *s_info;
  392. char *t_info;
  393. public:
  394. DTCResultInfo()
  395. : SimpleSection(resultInfoDefinition), szErrMsg(NULL),
  396. s_info(NULL), t_info(NULL)
  397. {
  398. }
  399. ~DTCResultInfo()
  400. {
  401. FREE_CLEAR(szErrMsg);
  402. FREE_CLEAR(s_info);
  403. FREE_CLEAR(t_info);
  404. }
  405. DTCResultInfo(const DTCResultInfo &orig) : SimpleSection(orig)
  406. {
  407. if (orig.szErrMsg) {
  408. szErrMsg = STRDUP(orig.szErrMsg);
  409. set_tag(3, szErrMsg, strlen(szErrMsg));
  410. }
  411. if (orig.s_info) {
  412. s_info = NULL;
  413. set_server_info((DTCServerInfo *)orig.s_info);
  414. }
  415. if (orig.t_info) {
  416. t_info = NULL;
  417. set_time_info((DTCTimeInfo *)orig.t_info);
  418. }
  419. }
  420. inline virtual void Clean()
  421. {
  422. SimpleSection::Clean();
  423. FREE_CLEAR(szErrMsg);
  424. FREE_CLEAR(s_info);
  425. FREE_CLEAR(t_info);
  426. }
  427. void Copy(const DTCResultInfo &orig)
  428. {
  429. SimpleSection::Copy(orig);
  430. FREE_CLEAR(szErrMsg);
  431. if (orig.szErrMsg) {
  432. szErrMsg = STRDUP(orig.szErrMsg);
  433. set_tag(3, szErrMsg, strlen(szErrMsg));
  434. }
  435. FREE_CLEAR(s_info);
  436. if (orig.s_info) {
  437. set_server_info((DTCServerInfo *)orig.s_info);
  438. }
  439. FREE_CLEAR(t_info);
  440. if (orig.t_info) {
  441. set_time_info((DTCTimeInfo *)orig.t_info);
  442. }
  443. }
  444. void set_error(int err, const char *from, const char *msg)
  445. {
  446. set_tag(1, err);
  447. if (from)
  448. set_tag(2, (char *)from, strlen(from));
  449. if (msg)
  450. set_tag(3, (char *)msg, strlen(msg));
  451. }
  452. void set_error_dup(int err, const char *from, const char *msg)
  453. {
  454. FREE_IF(szErrMsg);
  455. szErrMsg = STRDUP(msg);
  456. set_tag(1, err);
  457. if (from)
  458. set_tag(2, (char *)from, strlen(from));
  459. if (msg)
  460. set_tag(3, szErrMsg, strlen(szErrMsg));
  461. }
  462. int result_code(void) const
  463. {
  464. return tagValue[1].s64;
  465. }
  466. const char *error_from(void) const
  467. {
  468. return tagValue[2].str.ptr;
  469. }
  470. const char *error_message(void) const
  471. {
  472. return tagValue[3].str.ptr;
  473. }
  474. uint64_t affected_rows(void) const
  475. {
  476. return tagValue[4].s64;
  477. }
  478. void set_affected_rows(uint64_t nr)
  479. {
  480. set_tag(4, nr);
  481. }
  482. uint64_t total_rows(void) const
  483. {
  484. return tagValue[5].s64;
  485. }
  486. void set_total_rows(uint64_t nr)
  487. {
  488. set_tag(5, nr);
  489. }
  490. uint64_t insert_id(void) const
  491. {
  492. return tagValue[6].u64;
  493. }
  494. void set_insert_id(uint64_t nr)
  495. {
  496. set_tag(6, nr);
  497. }
  498. char *server_info(void) const
  499. {
  500. if (tagValue[7].str.len != sizeof(DTCServerInfo))
  501. return NULL;
  502. return tagValue[7].str.ptr;
  503. }
  504. void set_server_info(DTCServerInfo *si)
  505. {
  506. FREE_IF(s_info);
  507. int len = sizeof(DTCServerInfo);
  508. s_info = (char *)CALLOC(1, len);
  509. memcpy(s_info, si, len);
  510. set_tag(7, s_info, len);
  511. return;
  512. }
  513. char *time_info(void) const
  514. {
  515. if (tagValue[7].str.len != sizeof(DTCTimeInfo))
  516. return NULL;
  517. return tagValue[7].str.ptr;
  518. }
  519. void set_time_info(DTCTimeInfo *ti)
  520. {
  521. FREE_IF(t_info);
  522. int len = sizeof(DTCTimeInfo);
  523. t_info = (char *)CALLOC(1, len);
  524. memcpy(t_info, ti, len);
  525. set_tag(7, t_info, len);
  526. return;
  527. }
  528. uint32_t Timestamp(void) const
  529. {
  530. return tagValue[8].s64;
  531. }
  532. void set_time_info(uint32_t nr)
  533. {
  534. set_tag(8, nr);
  535. }
  536. /*set hit flag by tomchen 20140604*/
  537. void set_hit_flag(uint32_t nr)
  538. {
  539. set_tag(9, nr);
  540. }
  541. uint32_t hit_flag() const
  542. {
  543. return tagValue[9].s64;
  544. };
  545. /*一个请求有多个key的时候,要统计这个请求不同key对应的业务命中率和计数命中率*/
  546. /*命中率字段中,前16位放业务命中率,后16位放技术命中率*/
  547. uint32_t get_tech_hit_num()
  548. {
  549. uint32_t uHitFlag = (uint32_t)hit_flag();
  550. uint32_t uTaskTechHitNum = uHitFlag & 0xFFFF;
  551. return uTaskTechHitNum;
  552. }
  553. uint32_t get_business_hit_num()
  554. {
  555. uint32_t uHitFlag = (uint32_t)hit_flag();
  556. uint32_t uTashBusinessHitNum = (uHitFlag & 0xFFFF0000) >> 16;
  557. return uTashBusinessHitNum;
  558. }
  559. void incr_tech_hit_num()
  560. {
  561. uint32_t uHitFlag = (uint32_t)hit_flag();
  562. uint32_t uTaskTechHitNum = uHitFlag & 0xFFFF;
  563. uTaskTechHitNum++;
  564. uHitFlag = uHitFlag & 0xFFFF0000;
  565. uHitFlag = uHitFlag | uTaskTechHitNum;
  566. set_hit_flag(uHitFlag);
  567. }
  568. void incr_bussiness_hit_num()
  569. {
  570. uint32_t uHitFlag = (uint32_t)hit_flag();
  571. uint32_t uTashBusinessHitNum = (uHitFlag & 0xFFFF0000) >> 16;
  572. uTashBusinessHitNum++;
  573. uTashBusinessHitNum = uTashBusinessHitNum << 16;
  574. uHitFlag = uHitFlag & 0xFFFF;
  575. uHitFlag = uHitFlag | uTashBusinessHitNum;
  576. set_hit_flag(uHitFlag);
  577. }
  578. };
  579. #endif