ng_info.cc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. #include <string.h>
  17. #include <stdio.h>
  18. #include "node_set.h"
  19. #include "node_list.h"
  20. #include "node_index.h"
  21. #include "ng_info.h"
  22. #include "node.h"
  23. #include "dtc_global.h"
  24. DTC_USING_NAMESPACE
  25. NGInfo::NGInfo() : nodegroup_info_(NULL)
  26. {
  27. memset(errmsg_, 0, sizeof(errmsg_));
  28. empty_node_count = 0;
  29. empty_startup_mode = CREATED;
  30. stat_used_nodegroup = g_stat_mgr.get_stat_int_counter(DTC_USED_NGS);
  31. stat_used_node = g_stat_mgr.get_stat_int_counter(DTC_USED_NODES);
  32. stat_dirty_node = g_stat_mgr.get_stat_int_counter(DTC_DIRTY_NODES);
  33. stat_empty_node = g_stat_mgr.get_stat_int_counter(DTC_EMPTY_NODES);
  34. stat_empty_node = 0;
  35. stat_used_row = g_stat_mgr.get_stat_int_counter(DTC_USED_ROWS);
  36. stat_dirty_row = g_stat_mgr.get_stat_int_counter(DTC_DIRTY_ROWS);
  37. }
  38. NGInfo::~NGInfo()
  39. {
  40. }
  41. Node NGInfo::allocate_node(void)
  42. {
  43. //优先在空闲链表分配
  44. NODE_SET *NS = find_free_ng();
  45. if (!NS) {
  46. /* 防止NodeGroup把内存碎片化,采用预分配 */
  47. static int step = DTCGlobal::pre_alloc_nodegroup_count;
  48. static int fail = 0;
  49. for (int i = 0; i < step; i++) {
  50. NS = allocate_ng();
  51. if (!NS) {
  52. if (i == 0)
  53. return Node();
  54. else {
  55. fail = 1;
  56. step = 1;
  57. break;
  58. }
  59. }
  60. free_list_add(NS);
  61. }
  62. /* find again */
  63. NS = find_free_ng();
  64. if (step < 256 && !fail)
  65. step *= 2;
  66. }
  67. Node node = NS->allocate_node();
  68. //NG中没有任何可分配的Node
  69. if (NS->is_full()) {
  70. list_del(NS);
  71. full_list_add(NS);
  72. }
  73. if (!node) {
  74. snprintf(errmsg_, sizeof(errmsg_),
  75. "PANIC: allocate node failed");
  76. return Node();
  77. }
  78. //statistic
  79. nodegroup_info_->ni_used_node++;
  80. stat_used_node = nodegroup_info_->ni_used_node;
  81. //insert to node_index
  82. I_INSERT(node);
  83. return node;
  84. }
  85. int NGInfo::release_node(Node &node)
  86. {
  87. NODE_SET *NS = node.Owner();
  88. if (NS->is_full()) {
  89. //NG挂入空闲链表
  90. list_del(NS);
  91. free_list_add(NS);
  92. }
  93. nodegroup_info_->ni_used_node--;
  94. stat_used_node = nodegroup_info_->ni_used_node;
  95. return node.Release();
  96. }
  97. Node NGInfo::dirty_node_head()
  98. {
  99. NODE_SET *sysNG = M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  100. if (!sysNG)
  101. return Node();
  102. return Node(sysNG, SYS_DIRTY_NODE_INDEX);
  103. }
  104. Node NGInfo::clean_node_head()
  105. {
  106. NODE_SET *sysNG = M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  107. if (!sysNG)
  108. return Node();
  109. return Node(sysNG, SYS_CLEAN_NODE_INDEX);
  110. }
  111. Node NGInfo::empty_node_head()
  112. {
  113. NODE_SET *sysNG = M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  114. if (!sysNG)
  115. return Node();
  116. return Node(sysNG, SYS_EMPTY_NODE_INDEX);
  117. }
  118. int NGInfo::insert_to_dirty_lru(Node node)
  119. {
  120. NODE_SET *sysNG = M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  121. Node dirtyNode(sysNG, SYS_DIRTY_NODE_INDEX);
  122. NODE_LIST_ADD(node, dirtyNode);
  123. return 0;
  124. }
  125. int NGInfo::insert_to_clean_lru(Node node)
  126. {
  127. NODE_SET *sysNG = M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  128. Node cleanNode(sysNG, SYS_CLEAN_NODE_INDEX);
  129. NODE_LIST_ADD(node, cleanNode);
  130. return 0;
  131. }
  132. int NGInfo::insert_to_empty_lru(Node node)
  133. {
  134. NODE_SET *sysNG = M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  135. Node emptyNode(sysNG, SYS_EMPTY_NODE_INDEX);
  136. NODE_LIST_ADD(node, emptyNode);
  137. return 0;
  138. }
  139. int NGInfo::remove_from_lru(Node node)
  140. {
  141. NODE_LIST_DEL(node);
  142. return 0;
  143. }
  144. NODE_SET *NGInfo::allocate_ng(void)
  145. {
  146. MEM_HANDLE_T v = M_CALLOC(NODE_SET::Size());
  147. if (INVALID_HANDLE == v) {
  148. snprintf(errmsg_, sizeof(errmsg_),
  149. "allocate nodegroup failed, %s", M_ERROR());
  150. return (NODE_SET *)0;
  151. }
  152. NODE_SET *NS = M_POINTER(NODE_SET, v);
  153. NS->do_init(nodegroup_info_->ni_min_id);
  154. nodegroup_info_->ni_min_id += NODE_GROUP_INCLUDE_NODES;
  155. nodegroup_info_->ni_used_ng++;
  156. stat_used_nodegroup = nodegroup_info_->ni_used_ng;
  157. return NS;
  158. }
  159. NODE_SET *NGInfo::find_free_ng(void)
  160. {
  161. //链表为空
  162. if (NG_LIST_EMPTY(&(nodegroup_info_->ni_free_head))) {
  163. return (NODE_SET *)0;
  164. }
  165. return NG_LIST_ENTRY(nodegroup_info_->ni_free_head.Next(), NODE_SET,
  166. ng_list);
  167. }
  168. void NGInfo::list_del(NODE_SET *NS)
  169. {
  170. NG_LIST_T *p = &(NS->ng_list);
  171. return NG_LIST_DEL(p);
  172. }
  173. #define EXPORT_NG_LIST_FUNCTION(name, member, function) \
  174. void NGInfo::name(NODE_SET *NS) \
  175. { \
  176. NG_LIST_T *p = &(NS->ng_list); \
  177. NG_LIST_T *head = &(nodegroup_info_->member); \
  178. return function(p, head); \
  179. }
  180. EXPORT_NG_LIST_FUNCTION(free_list_add, ni_free_head, NG_LIST_ADD)
  181. EXPORT_NG_LIST_FUNCTION(full_list_add, ni_full_head, NG_LIST_ADD)
  182. EXPORT_NG_LIST_FUNCTION(free_list_add_tail, ni_free_head, NG_LIST_ADD_TAIL)
  183. EXPORT_NG_LIST_FUNCTION(full_list_add_tail, ni_full_head, NG_LIST_ADD_TAIL)
  184. int NGInfo::init_header(NG_INFO_T *ni)
  185. {
  186. INIT_NG_LIST_HEAD(&(ni->ni_free_head));
  187. INIT_NG_LIST_HEAD(&(ni->ni_full_head));
  188. ni->ni_min_id = SYS_MIN_NODE_ID;
  189. /* init system reserved zone*/
  190. {
  191. NODE_SET *sysNG = allocate_ng();
  192. if (!sysNG)
  193. return -1;
  194. sysNG->system_reserved_init();
  195. ni->ni_sys_zone = M_HANDLE(sysNG);
  196. }
  197. ni->ni_used_ng = 1;
  198. ni->ni_used_node = 0;
  199. ni->ni_dirty_node = 0;
  200. ni->ni_used_row = 0;
  201. ni->ni_dirty_row = 0;
  202. stat_used_nodegroup = ni->ni_used_ng;
  203. stat_used_node = ni->ni_used_node;
  204. stat_dirty_node = ni->ni_dirty_node;
  205. stat_dirty_row = ni->ni_dirty_row;
  206. stat_used_row = ni->ni_used_row;
  207. stat_empty_node = 0;
  208. return 0;
  209. }
  210. int NGInfo::do_init(void)
  211. {
  212. //1. malloc ng_info mem.
  213. MEM_HANDLE_T v = M_CALLOC(sizeof(NG_INFO_T));
  214. if (INVALID_HANDLE == v) {
  215. snprintf(errmsg_, sizeof(errmsg_), "init nginfo failed, %s",
  216. M_ERROR());
  217. return -1;
  218. }
  219. //2. mapping
  220. nodegroup_info_ = M_POINTER(NG_INFO_T, v);
  221. //3. init header
  222. return init_header(nodegroup_info_);
  223. }
  224. int NGInfo::do_attach(MEM_HANDLE_T v)
  225. {
  226. if (INVALID_HANDLE == v) {
  227. snprintf(errmsg_, sizeof(errmsg_),
  228. "attach nginfo failed, memory handle = 0");
  229. return -1;
  230. }
  231. nodegroup_info_ = M_POINTER(NG_INFO_T, v);
  232. /* check system reserved zone:
  233. * 1. the present of empty lru list
  234. */
  235. {
  236. NODE_SET *sysNG =
  237. M_POINTER(NODE_SET, nodegroup_info_->ni_sys_zone);
  238. if (!sysNG)
  239. return -1;
  240. int ret = sysNG->system_reserved_check();
  241. if (ret < 0)
  242. return ret;
  243. if (ret > 0) {
  244. empty_startup_mode = UPGRADED;
  245. } else {
  246. empty_startup_mode = ATTACHED;
  247. }
  248. }
  249. return 0;
  250. }
  251. int NGInfo::do_detach(void)
  252. {
  253. nodegroup_info_ = NULL;
  254. return 0;
  255. }