当前位置:   article > 正文

数据结构开发(11):双向循环链表的实现

双向循环链表 消息队列

0.目录

1.双向循环链表的实现
2.小结

1.双向循环链表的实现

本节目标:

  • 使用 Linux 内核链表实现 StLib 中的双向循环链表
  • template <typename T> class DualCircleList;

1250397-20181218161549358-1384272800.png

StLib 中双向循环链表的设计思路:

  • 数据结点之间在逻辑上构成双向循环链表,头结点仅用于结点的定位。

1250397-20181218161611091-1380254747.png

实现思路:

  • 通过模板定义 DualCircleList 类,继承自 DualLinkList
  • 在 DualCircleList 内部使用Linux内核链表进行实现
  • 使用 struct list_head 定义 DualCircleList 的头结点
  • 特殊处理:循环遍历时忽略头结点

实现要点:

  • 通过 list_head 进行目标结点定位( position(i) )
  • 通过 list_entry 将 list_head 指针转换为目标结点指针
  • 通过 list_for_each 实现 int find(const T& e) 函数
  • 遍历函数中的 next() 和 pre() 需要考虑跳过头结点

双向循环链表的实现(DualLinkList.h):
使用到的LinuxList.h头文件放在文字尾部:LinuxList.h
DualLinkList.h

  1. #ifndef DUALCIRCLELIST_H
  2. #define DUALCIRCLELIST_H
  3. #include "LinuxList.h"
  4. #include "DualLinkList.h"
  5. namespace StLib
  6. {
  7. template <typename T>
  8. class DualCircleList : public DualLinkList<T>
  9. {
  10. protected:
  11. struct Node : public Object
  12. {
  13. list_head head;
  14. T value;
  15. };
  16. list_head m_header;
  17. list_head* m_current;
  18. list_head* position(int i) const
  19. {
  20. list_head* ret = const_cast<list_head*>(&m_header);
  21. for(int p=0; p<i; p++)
  22. {
  23. ret = ret->next;
  24. }
  25. return ret;
  26. }
  27. int mod(int i) const
  28. {
  29. return (this->m_length == 0) ? 0 : (i % this->m_length);
  30. }
  31. public:
  32. DualCircleList()
  33. {
  34. this->m_length = 0;
  35. this->m_step = 1;
  36. m_current = NULL;
  37. INIT_LIST_HEAD(&m_header);
  38. }
  39. bool insert(const T& e)
  40. {
  41. return insert(this->m_length, e);
  42. }
  43. bool insert(int i, const T& e)
  44. {
  45. bool ret = true;
  46. Node* node = new Node();
  47. i = i % (this->m_length + 1);
  48. if( node != NULL )
  49. {
  50. node->value = e;
  51. list_add_tail(&node->head, position(i)->next);
  52. this->m_length++;
  53. }
  54. else
  55. {
  56. THROW_EXCEPTION(NoEnoughMemoryException, "No memory to insert new element ...");
  57. }
  58. return ret;
  59. }
  60. bool remove(int i)
  61. {
  62. bool ret = true;
  63. i = mod(i);
  64. ret = ((0 <= i) && (i < this->m_length));
  65. if( ret )
  66. {
  67. list_head* toDel = position(i)->next;
  68. if( m_current == toDel )
  69. {
  70. m_current = toDel->next;
  71. }
  72. list_del(toDel);
  73. this->m_length--;
  74. delete list_entry(toDel, Node, head);
  75. }
  76. return ret;
  77. }
  78. bool set(int i, const T& e)
  79. {
  80. bool ret = true;
  81. i = mod(i);
  82. ret = ((0 <= i) && (i < this->m_length));
  83. if( ret )
  84. {
  85. list_entry(position(i)->next, Node, head)->value = e;
  86. }
  87. return ret;
  88. }
  89. T get(int i) const
  90. {
  91. T ret;
  92. if( get(i, ret) )
  93. {
  94. return ret;
  95. }
  96. else
  97. {
  98. THROW_EXCEPTION(IndexOutOfBoundsException, "Invalid parameter i to get element ...");
  99. }
  100. return ret;
  101. }
  102. bool get(int i, T& e) const
  103. {
  104. bool ret = true;
  105. i = mod(i);
  106. ret = ((0 <= i) && (i < this->m_length));
  107. if( ret )
  108. {
  109. e = list_entry(position(i)->next, Node, head)->value;
  110. }
  111. return ret;
  112. }
  113. int find(const T& e) const
  114. {
  115. int ret = -1;
  116. int i = 0;
  117. list_head* slider = NULL;
  118. list_for_each(slider, &m_header)
  119. {
  120. if( list_entry(slider, Node, head)->value == e )
  121. {
  122. ret = i;
  123. break;
  124. }
  125. i++;
  126. }
  127. return ret;
  128. }
  129. int length() const
  130. {
  131. return this->m_length;
  132. }
  133. void clear()
  134. {
  135. while( this->m_length > 0 )
  136. {
  137. remove(0);
  138. }
  139. }
  140. bool move(int i, int step = 1)
  141. {
  142. bool ret = (step > 0);
  143. i = mod(i);
  144. ret = ret && ((0 <= i) && (i < this->m_length));
  145. if( ret )
  146. {
  147. m_current = position(i)->next;
  148. this->m_step = step;
  149. }
  150. return ret;
  151. }
  152. bool end()
  153. {
  154. return (m_current == NULL) || (this->m_length == 0);
  155. }
  156. virtual T current()
  157. {
  158. if( !end() )
  159. {
  160. return list_entry(m_current, Node, head)->value;
  161. }
  162. else
  163. {
  164. THROW_EXCEPTION(InvalidOperationException, "No value at current position ...");
  165. }
  166. }
  167. bool next()
  168. {
  169. int i = 0;
  170. while( (i < this->m_step) && !end() )
  171. {
  172. if( m_current != &m_header )
  173. {
  174. m_current = m_current->next;
  175. i++;
  176. }
  177. else
  178. {
  179. m_current = m_current->next;
  180. }
  181. }
  182. if( m_current == &m_header )
  183. {
  184. m_current = m_current->next;
  185. }
  186. return (i == this->m_step);
  187. }
  188. bool pre()
  189. {
  190. int i = 0;
  191. while( (i < this->m_step) && !end() )
  192. {
  193. if( m_current != &m_header )
  194. {
  195. m_current = m_current->prev;
  196. i++;
  197. }
  198. else
  199. {
  200. m_current = m_current->prev;
  201. }
  202. }
  203. if( m_current == &m_header )
  204. {
  205. m_current = m_current->prev;
  206. }
  207. return (i == this->m_step);
  208. }
  209. ~DualCircleList()
  210. {
  211. clear();
  212. }
  213. };
  214. }
  215. #endif // DUALCIRCLELIST_H

main.cpp测试

  1. #include <iostream>
  2. #include "DualCircleList.h"
  3. using namespace std;
  4. using namespace StLib;
  5. int main()
  6. {
  7. DualCircleList<int> d1;
  8. for(int i=0; i<5; i++)
  9. {
  10. d1.insert(0, i);
  11. d1.insert(0, 5);
  12. }
  13. cout << "begin" << endl;
  14. d1.move(d1.length()-1);
  15. while( d1.find(5) != -1 )
  16. {
  17. if( d1.current() == 5 )
  18. {
  19. cout << d1.current() << endl;
  20. d1.remove(d1.find(d1.current()));
  21. }
  22. else
  23. {
  24. d1.pre();
  25. }
  26. }
  27. cout << "end" << endl;
  28. // for(int i=0; i<d1.length(); i++)
  29. // {
  30. // cout << d1.get(i) << endl;
  31. // }
  32. for(int i=0; i<10; i++)
  33. {
  34. cout << d1.get(i) << endl;
  35. }
  36. return 0;
  37. }

运行结果为:

  1. begin
  2. 5
  3. 5
  4. 5
  5. 5
  6. 5
  7. end
  8. 4
  9. 3
  10. 2
  11. 1
  12. 0
  13. 4
  14. 3
  15. 2
  16. 1
  17. 0

思考题——下面代码中的 pn1 和 pn2 是否相等?为什么?
1250397-20181218161708587-1540721591.png

2.小结

  • Linux内核链表是带头结点的双向循环链表
  • DualCircleList 使用Linux内核链表进行内部实现
  • DualCircleList 在循环遍历时需要跳过头结点
  • list_head 指针转换为目标结点指针时,使用 list_entry 宏

LinuxList.h
需要将LinuxList.h中的new改成node。

  1. #ifndef _LINUX_LIST_H
  2. #define _LINUX_LIST_H
  3. // #include <linux/types.h>
  4. // #include <linux/stddef.h>
  5. // #include <linux/poison.h>
  6. // #include <linux/prefetch.h>
  7. #ifndef offsetof
  8. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  9. #endif
  10. #ifndef container_of
  11. #define container_of(ptr, type, member) ((type *)((char *)ptr - offsetof(type,member)))
  12. #endif
  13. #define prefetch(x) ((void)x)
  14. #define LIST_POISON1 (NULL)
  15. #define LIST_POISON2 (NULL)
  16. struct list_head {
  17. struct list_head *next, *prev;
  18. };
  19. struct hlist_head {
  20. struct hlist_node *first;
  21. };
  22. struct hlist_node {
  23. struct hlist_node *next, **pprev;
  24. };
  25. /*
  26. * Simple doubly linked list implementation.
  27. *
  28. * Some of the internal functions ("__xxx") are useful when
  29. * manipulating whole lists rather than single entries, as
  30. * sometimes we already know the next/prev entries and we can
  31. * generate better code by using them directly rather than
  32. * using the generic single-entry routines.
  33. */
  34. #define LIST_HEAD_INIT(name) { &(name), &(name) }
  35. #define LIST_HEAD(name) \
  36. struct list_head name = LIST_HEAD_INIT(name)
  37. static void INIT_LIST_HEAD(struct list_head *list)
  38. {
  39. list->next = list;
  40. list->prev = list;
  41. }
  42. /*
  43. * Insert a new entry between two known consecutive entries.
  44. *
  45. * This is only for internal list manipulation where we know
  46. * the prev/next entries already!
  47. */
  48. #ifndef CONFIG_DEBUG_LIST
  49. static void __list_add(struct list_head *node,
  50. struct list_head *prev,
  51. struct list_head *next)
  52. {
  53. next->prev = node;
  54. node->next = next;
  55. node->prev = prev;
  56. prev->next = node;
  57. }
  58. #else
  59. extern void __list_add(struct list_head *node,
  60. struct list_head *prev,
  61. struct list_head *next);
  62. #endif
  63. /**
  64. * list_add - add a new entry
  65. * @new: new entry to be added
  66. * @head: list head to add it after
  67. *
  68. * Insert a new entry after the specified head.
  69. * This is good for implementing stacks.
  70. */
  71. static void list_add(struct list_head *node, struct list_head *head)
  72. {
  73. __list_add(node, head, head->next);
  74. }
  75. /**
  76. * list_add_tail - add a new entry
  77. * @new: new entry to be added
  78. * @head: list head to add it before
  79. *
  80. * Insert a new entry before the specified head.
  81. * This is useful for implementing queues.
  82. */
  83. static void list_add_tail(struct list_head *node, struct list_head *head)
  84. {
  85. __list_add(node, head->prev, head);
  86. }
  87. /*
  88. * Delete a list entry by making the prev/next entries
  89. * point to each other.
  90. *
  91. * This is only for internal list manipulation where we know
  92. * the prev/next entries already!
  93. */
  94. static void __list_del(struct list_head * prev, struct list_head * next)
  95. {
  96. next->prev = prev;
  97. prev->next = next;
  98. }
  99. /**
  100. * list_del - deletes entry from list.
  101. * @entry: the element to delete from the list.
  102. * Note: list_empty() on entry does not return true after this, the entry is
  103. * in an undefined state.
  104. */
  105. #ifndef CONFIG_DEBUG_LIST
  106. static void __list_del_entry(struct list_head *entry)
  107. {
  108. __list_del(entry->prev, entry->next);
  109. }
  110. static void list_del(struct list_head *entry)
  111. {
  112. __list_del(entry->prev, entry->next);
  113. entry->next = LIST_POISON1;
  114. entry->prev = LIST_POISON2;
  115. }
  116. #else
  117. extern void __list_del_entry(struct list_head *entry);
  118. extern void list_del(struct list_head *entry);
  119. #endif
  120. /**
  121. * list_replace - replace old entry by new one
  122. * @old : the element to be replaced
  123. * @new : the new element to insert
  124. *
  125. * If @old was empty, it will be overwritten.
  126. */
  127. static void list_replace(struct list_head *old,
  128. struct list_head *node)
  129. {
  130. node->next = old->next;
  131. node->next->prev = node;
  132. node->prev = old->prev;
  133. node->prev->next = node;
  134. }
  135. static void list_replace_init(struct list_head *old,
  136. struct list_head *node)
  137. {
  138. list_replace(old, node);
  139. INIT_LIST_HEAD(old);
  140. }
  141. /**
  142. * list_del_init - deletes entry from list and reinitialize it.
  143. * @entry: the element to delete from the list.
  144. */
  145. static void list_del_init(struct list_head *entry)
  146. {
  147. __list_del_entry(entry);
  148. INIT_LIST_HEAD(entry);
  149. }
  150. /**
  151. * list_move - delete from one list and add as another's head
  152. * @list: the entry to move
  153. * @head: the head that will precede our entry
  154. */
  155. static void list_move(struct list_head *list, struct list_head *head)
  156. {
  157. __list_del_entry(list);
  158. list_add(list, head);
  159. }
  160. /**
  161. * list_move_tail - delete from one list and add as another's tail
  162. * @list: the entry to move
  163. * @head: the head that will follow our entry
  164. */
  165. static void list_move_tail(struct list_head *list,
  166. struct list_head *head)
  167. {
  168. __list_del_entry(list);
  169. list_add_tail(list, head);
  170. }
  171. /**
  172. * list_is_last - tests whether @list is the last entry in list @head
  173. * @list: the entry to test
  174. * @head: the head of the list
  175. */
  176. static int list_is_last(const struct list_head *list,
  177. const struct list_head *head)
  178. {
  179. return list->next == head;
  180. }
  181. /**
  182. * list_empty - tests whether a list is empty
  183. * @head: the list to test.
  184. */
  185. static int list_empty(const struct list_head *head)
  186. {
  187. return head->next == head;
  188. }
  189. /**
  190. * list_empty_careful - tests whether a list is empty and not being modified
  191. * @head: the list to test
  192. *
  193. * Description:
  194. * tests whether a list is empty _and_ checks that no other CPU might be
  195. * in the process of modifying either member (next or prev)
  196. *
  197. * NOTE: using list_empty_careful() without synchronization
  198. * can only be safe if the only activity that can happen
  199. * to the list entry is list_del_init(). Eg. it cannot be used
  200. * if another CPU could re-list_add() it.
  201. */
  202. static int list_empty_careful(const struct list_head *head)
  203. {
  204. struct list_head *next = head->next;
  205. return (next == head) && (next == head->prev);
  206. }
  207. /**
  208. * list_rotate_left - rotate the list to the left
  209. * @head: the head of the list
  210. */
  211. static void list_rotate_left(struct list_head *head)
  212. {
  213. struct list_head *first;
  214. if (!list_empty(head)) {
  215. first = head->next;
  216. list_move_tail(first, head);
  217. }
  218. }
  219. /**
  220. * list_is_singular - tests whether a list has just one entry.
  221. * @head: the list to test.
  222. */
  223. static int list_is_singular(const struct list_head *head)
  224. {
  225. return !list_empty(head) && (head->next == head->prev);
  226. }
  227. static void __list_cut_position(struct list_head *list,
  228. struct list_head *head, struct list_head *entry)
  229. {
  230. struct list_head *new_first = entry->next;
  231. list->next = head->next;
  232. list->next->prev = list;
  233. list->prev = entry;
  234. entry->next = list;
  235. head->next = new_first;
  236. new_first->prev = head;
  237. }
  238. /**
  239. * list_cut_position - cut a list into two
  240. * @list: a new list to add all removed entries
  241. * @head: a list with entries
  242. * @entry: an entry within head, could be the head itself
  243. * and if so we won't cut the list
  244. *
  245. * This helper moves the initial part of @head, up to and
  246. * including @entry, from @head to @list. You should
  247. * pass on @entry an element you know is on @head. @list
  248. * should be an empty list or a list you do not care about
  249. * losing its data.
  250. *
  251. */
  252. static void list_cut_position(struct list_head *list,
  253. struct list_head *head, struct list_head *entry)
  254. {
  255. if (list_empty(head))
  256. return;
  257. if (list_is_singular(head) &&
  258. (head->next != entry && head != entry))
  259. return;
  260. if (entry == head)
  261. INIT_LIST_HEAD(list);
  262. else
  263. __list_cut_position(list, head, entry);
  264. }
  265. static void __list_splice(const struct list_head *list,
  266. struct list_head *prev,
  267. struct list_head *next)
  268. {
  269. struct list_head *first = list->next;
  270. struct list_head *last = list->prev;
  271. first->prev = prev;
  272. prev->next = first;
  273. last->next = next;
  274. next->prev = last;
  275. }
  276. /**
  277. * list_splice - join two lists, this is designed for stacks
  278. * @list: the new list to add.
  279. * @head: the place to add it in the first list.
  280. */
  281. static void list_splice(const struct list_head *list,
  282. struct list_head *head)
  283. {
  284. if (!list_empty(list))
  285. __list_splice(list, head, head->next);
  286. }
  287. /**
  288. * list_splice_tail - join two lists, each list being a queue
  289. * @list: the new list to add.
  290. * @head: the place to add it in the first list.
  291. */
  292. static void list_splice_tail(struct list_head *list,
  293. struct list_head *head)
  294. {
  295. if (!list_empty(list))
  296. __list_splice(list, head->prev, head);
  297. }
  298. /**
  299. * list_splice_init - join two lists and reinitialise the emptied list.
  300. * @list: the new list to add.
  301. * @head: the place to add it in the first list.
  302. *
  303. * The list at @list is reinitialised
  304. */
  305. static void list_splice_init(struct list_head *list,
  306. struct list_head *head)
  307. {
  308. if (!list_empty(list)) {
  309. __list_splice(list, head, head->next);
  310. INIT_LIST_HEAD(list);
  311. }
  312. }
  313. /**
  314. * list_splice_tail_init - join two lists and reinitialise the emptied list
  315. * @list: the new list to add.
  316. * @head: the place to add it in the first list.
  317. *
  318. * Each of the lists is a queue.
  319. * The list at @list is reinitialised
  320. */
  321. static void list_splice_tail_init(struct list_head *list,
  322. struct list_head *head)
  323. {
  324. if (!list_empty(list)) {
  325. __list_splice(list, head->prev, head);
  326. INIT_LIST_HEAD(list);
  327. }
  328. }
  329. /**
  330. * list_entry - get the struct for this entry
  331. * @ptr: the &struct list_head pointer.
  332. * @type: the type of the struct this is embedded in.
  333. * @member: the name of the list_struct within the struct.
  334. */
  335. #define list_entry(ptr, type, member) \
  336. container_of(ptr, type, member)
  337. /**
  338. * list_first_entry - get the first element from a list
  339. * @ptr: the list head to take the element from.
  340. * @type: the type of the struct this is embedded in.
  341. * @member: the name of the list_struct within the struct.
  342. *
  343. * Note, that list is expected to be not empty.
  344. */
  345. #define list_first_entry(ptr, type, member) \
  346. list_entry((ptr)->next, type, member)
  347. /**
  348. * list_for_each - iterate over a list
  349. * @pos: the &struct list_head to use as a loop cursor.
  350. * @head: the head for your list.
  351. */
  352. #define list_for_each(pos, head) \
  353. for (pos = (head)->next; prefetch(pos->next), pos != (head); \
  354. pos = pos->next)
  355. /**
  356. * __list_for_each - iterate over a list
  357. * @pos: the &struct list_head to use as a loop cursor.
  358. * @head: the head for your list.
  359. *
  360. * This variant differs from list_for_each() in that it's the
  361. * simplest possible list iteration code, no prefetching is done.
  362. * Use this for code that knows the list to be very short (empty
  363. * or 1 entry) most of the time.
  364. */
  365. #define __list_for_each(pos, head) \
  366. for (pos = (head)->next; pos != (head); pos = pos->next)
  367. /**
  368. * list_for_each_prev - iterate over a list backwards
  369. * @pos: the &struct list_head to use as a loop cursor.
  370. * @head: the head for your list.
  371. */
  372. #define list_for_each_prev(pos, head) \
  373. for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
  374. pos = pos->prev)
  375. /**
  376. * list_for_each_safe - iterate over a list safe against removal of list entry
  377. * @pos: the &struct list_head to use as a loop cursor.
  378. * @n: another &struct list_head to use as temporary storage
  379. * @head: the head for your list.
  380. */
  381. #define list_for_each_safe(pos, n, head) \
  382. for (pos = (head)->next, n = pos->next; pos != (head); \
  383. pos = n, n = pos->next)
  384. /**
  385. * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
  386. * @pos: the &struct list_head to use as a loop cursor.
  387. * @n: another &struct list_head to use as temporary storage
  388. * @head: the head for your list.
  389. */
  390. #define list_for_each_prev_safe(pos, n, head) \
  391. for (pos = (head)->prev, n = pos->prev; \
  392. prefetch(pos->prev), pos != (head); \
  393. pos = n, n = pos->prev)
  394. /**
  395. * list_for_each_entry - iterate over list of given type
  396. * @pos: the type * to use as a loop cursor.
  397. * @head: the head for your list.
  398. * @member: the name of the list_struct within the struct.
  399. */
  400. #define list_for_each_entry(pos, head, member) \
  401. for (pos = list_entry((head)->next, typeof(*pos), member); \
  402. prefetch(pos->member.next), &pos->member != (head); \
  403. pos = list_entry(pos->member.next, typeof(*pos), member))
  404. /**
  405. * list_for_each_entry_reverse - iterate backwards over list of given type.
  406. * @pos: the type * to use as a loop cursor.
  407. * @head: the head for your list.
  408. * @member: the name of the list_struct within the struct.
  409. */
  410. #define list_for_each_entry_reverse(pos, head, member) \
  411. for (pos = list_entry((head)->prev, typeof(*pos), member); \
  412. prefetch(pos->member.prev), &pos->member != (head); \
  413. pos = list_entry(pos->member.prev, typeof(*pos), member))
  414. /**
  415. * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
  416. * @pos: the type * to use as a start point
  417. * @head: the head of the list
  418. * @member: the name of the list_struct within the struct.
  419. *
  420. * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
  421. */
  422. #define list_prepare_entry(pos, head, member) \
  423. ((pos) ? : list_entry(head, typeof(*pos), member))
  424. /**
  425. * list_for_each_entry_continue - continue iteration over list of given type
  426. * @pos: the type * to use as a loop cursor.
  427. * @head: the head for your list.
  428. * @member: the name of the list_struct within the struct.
  429. *
  430. * Continue to iterate over list of given type, continuing after
  431. * the current position.
  432. */
  433. #define list_for_each_entry_continue(pos, head, member) \
  434. for (pos = list_entry(pos->member.next, typeof(*pos), member); \
  435. prefetch(pos->member.next), &pos->member != (head); \
  436. pos = list_entry(pos->member.next, typeof(*pos), member))
  437. /**
  438. * list_for_each_entry_continue_reverse - iterate backwards from the given point
  439. * @pos: the type * to use as a loop cursor.
  440. * @head: the head for your list.
  441. * @member: the name of the list_struct within the struct.
  442. *
  443. * Start to iterate over list of given type backwards, continuing after
  444. * the current position.
  445. */
  446. #define list_for_each_entry_continue_reverse(pos, head, member) \
  447. for (pos = list_entry(pos->member.prev, typeof(*pos), member); \
  448. prefetch(pos->member.prev), &pos->member != (head); \
  449. pos = list_entry(pos->member.prev, typeof(*pos), member))
  450. /**
  451. * list_for_each_entry_from - iterate over list of given type from the current point
  452. * @pos: the type * to use as a loop cursor.
  453. * @head: the head for your list.
  454. * @member: the name of the list_struct within the struct.
  455. *
  456. * Iterate over list of given type, continuing from current position.
  457. */
  458. #define list_for_each_entry_from(pos, head, member) \
  459. for (; prefetch(pos->member.next), &pos->member != (head); \
  460. pos = list_entry(pos->member.next, typeof(*pos), member))
  461. /**
  462. * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  463. * @pos: the type * to use as a loop cursor.
  464. * @n: another type * to use as temporary storage
  465. * @head: the head for your list.
  466. * @member: the name of the list_struct within the struct.
  467. */
  468. #define list_for_each_entry_safe(pos, n, head, member) \
  469. for (pos = list_entry((head)->next, typeof(*pos), member), \
  470. n = list_entry(pos->member.next, typeof(*pos), member); \
  471. &pos->member != (head); \
  472. pos = n, n = list_entry(n->member.next, typeof(*n), member))
  473. /**
  474. * list_for_each_entry_safe_continue - continue list iteration safe against removal
  475. * @pos: the type * to use as a loop cursor.
  476. * @n: another type * to use as temporary storage
  477. * @head: the head for your list.
  478. * @member: the name of the list_struct within the struct.
  479. *
  480. * Iterate over list of given type, continuing after current point,
  481. * safe against removal of list entry.
  482. */
  483. #define list_for_each_entry_safe_continue(pos, n, head, member) \
  484. for (pos = list_entry(pos->member.next, typeof(*pos), member), \
  485. n = list_entry(pos->member.next, typeof(*pos), member); \
  486. &pos->member != (head); \
  487. pos = n, n = list_entry(n->member.next, typeof(*n), member))
  488. /**
  489. * list_for_each_entry_safe_from - iterate over list from current point safe against removal
  490. * @pos: the type * to use as a loop cursor.
  491. * @n: another type * to use as temporary storage
  492. * @head: the head for your list.
  493. * @member: the name of the list_struct within the struct.
  494. *
  495. * Iterate over list of given type from current point, safe against
  496. * removal of list entry.
  497. */
  498. #define list_for_each_entry_safe_from(pos, n, head, member) \
  499. for (n = list_entry(pos->member.next, typeof(*pos), member); \
  500. &pos->member != (head); \
  501. pos = n, n = list_entry(n->member.next, typeof(*n), member))
  502. /**
  503. * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
  504. * @pos: the type * to use as a loop cursor.
  505. * @n: another type * to use as temporary storage
  506. * @head: the head for your list.
  507. * @member: the name of the list_struct within the struct.
  508. *
  509. * Iterate backwards over list of given type, safe against removal
  510. * of list entry.
  511. */
  512. #define list_for_each_entry_safe_reverse(pos, n, head, member) \
  513. for (pos = list_entry((head)->prev, typeof(*pos), member), \
  514. n = list_entry(pos->member.prev, typeof(*pos), member); \
  515. &pos->member != (head); \
  516. pos = n, n = list_entry(n->member.prev, typeof(*n), member))
  517. /**
  518. * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
  519. * @pos: the loop cursor used in the list_for_each_entry_safe loop
  520. * @n: temporary storage used in list_for_each_entry_safe
  521. * @member: the name of the list_struct within the struct.
  522. *
  523. * list_safe_reset_next is not safe to use in general if the list may be
  524. * modified concurrently (eg. the lock is dropped in the loop body). An
  525. * exception to this is if the cursor element (pos) is pinned in the list,
  526. * and list_safe_reset_next is called after re-taking the lock and before
  527. * completing the current iteration of the loop body.
  528. */
  529. #define list_safe_reset_next(pos, n, member) \
  530. n = list_entry(pos->member.next, typeof(*pos), member)
  531. /*
  532. * Double linked lists with a single pointer list head.
  533. * Mostly useful for hash tables where the two pointer list head is
  534. * too wasteful.
  535. * You lose the ability to access the tail in O(1).
  536. */
  537. #define HLIST_HEAD_INIT { .first = NULL }
  538. #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
  539. #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
  540. static void INIT_HLIST_NODE(struct hlist_node *h)
  541. {
  542. h->next = NULL;
  543. h->pprev = NULL;
  544. }
  545. static int hlist_unhashed(const struct hlist_node *h)
  546. {
  547. return !h->pprev;
  548. }
  549. static int hlist_empty(const struct hlist_head *h)
  550. {
  551. return !h->first;
  552. }
  553. static void __hlist_del(struct hlist_node *n)
  554. {
  555. struct hlist_node *next = n->next;
  556. struct hlist_node **pprev = n->pprev;
  557. *pprev = next;
  558. if (next)
  559. next->pprev = pprev;
  560. }
  561. static void hlist_del(struct hlist_node *n)
  562. {
  563. __hlist_del(n);
  564. n->next = LIST_POISON1;
  565. n->pprev = LIST_POISON2;
  566. }
  567. static void hlist_del_init(struct hlist_node *n)
  568. {
  569. if (!hlist_unhashed(n)) {
  570. __hlist_del(n);
  571. INIT_HLIST_NODE(n);
  572. }
  573. }
  574. static void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
  575. {
  576. struct hlist_node *first = h->first;
  577. n->next = first;
  578. if (first)
  579. first->pprev = &n->next;
  580. h->first = n;
  581. n->pprev = &h->first;
  582. }
  583. /* next must be != NULL */
  584. static void hlist_add_before(struct hlist_node *n,
  585. struct hlist_node *next)
  586. {
  587. n->pprev = next->pprev;
  588. n->next = next;
  589. next->pprev = &n->next;
  590. *(n->pprev) = n;
  591. }
  592. static void hlist_add_after(struct hlist_node *n,
  593. struct hlist_node *next)
  594. {
  595. next->next = n->next;
  596. n->next = next;
  597. next->pprev = &n->next;
  598. if(next->next)
  599. next->next->pprev = &next->next;
  600. }
  601. /* after that we'll appear to be on some hlist and hlist_del will work */
  602. static void hlist_add_fake(struct hlist_node *n)
  603. {
  604. n->pprev = &n->next;
  605. }
  606. /*
  607. * Move a list from one list head to another. Fixup the pprev
  608. * reference of the first entry if it exists.
  609. */
  610. static void hlist_move_list(struct hlist_head *old,
  611. struct hlist_head *node)
  612. {
  613. node->first = old->first;
  614. if (node->first)
  615. node->first->pprev = &node->first;
  616. old->first = NULL;
  617. }
  618. #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
  619. #define hlist_for_each(pos, head) \
  620. for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
  621. pos = pos->next)
  622. #define hlist_for_each_safe(pos, n, head) \
  623. for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
  624. pos = n)
  625. /**
  626. * hlist_for_each_entry - iterate over list of given type
  627. * @tpos: the type * to use as a loop cursor.
  628. * @pos: the &struct hlist_node to use as a loop cursor.
  629. * @head: the head for your list.
  630. * @member: the name of the hlist_node within the struct.
  631. */
  632. #define hlist_for_each_entry(tpos, pos, head, member) \
  633. for (pos = (head)->first; \
  634. pos && ({ prefetch(pos->next); 1;}) && \
  635. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  636. pos = pos->next)
  637. /**
  638. * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
  639. * @tpos: the type * to use as a loop cursor.
  640. * @pos: the &struct hlist_node to use as a loop cursor.
  641. * @member: the name of the hlist_node within the struct.
  642. */
  643. #define hlist_for_each_entry_continue(tpos, pos, member) \
  644. for (pos = (pos)->next; \
  645. pos && ({ prefetch(pos->next); 1;}) && \
  646. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  647. pos = pos->next)
  648. /**
  649. * hlist_for_each_entry_from - iterate over a hlist continuing from current point
  650. * @tpos: the type * to use as a loop cursor.
  651. * @pos: the &struct hlist_node to use as a loop cursor.
  652. * @member: the name of the hlist_node within the struct.
  653. */
  654. #define hlist_for_each_entry_from(tpos, pos, member) \
  655. for (; pos && ({ prefetch(pos->next); 1;}) && \
  656. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  657. pos = pos->next)
  658. /**
  659. * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  660. * @tpos: the type * to use as a loop cursor.
  661. * @pos: the &struct hlist_node to use as a loop cursor.
  662. * @n: another &struct hlist_node to use as temporary storage
  663. * @head: the head for your list.
  664. * @member: the name of the hlist_node within the struct.
  665. */
  666. #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
  667. for (pos = (head)->first; \
  668. pos && ({ n = pos->next; 1; }) && \
  669. ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
  670. pos = n)
  671. #endif

转载于:https://www.cnblogs.com/PyLearn/p/10138644.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/128108
推荐阅读
相关标签
  

闽ICP备14008679号