Commit 7fd44c96 7fd44c960d249559d30fca5c5993ebc9ba227650 by Sergey Poznyakoff

Rewritten to reduce the time of list traversal.

1 parent cee31522
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
22 #include <errno.h> 22 #include <errno.h>
23 #include <stdlib.h> 23 #include <stdlib.h>
24 24
25 #include <mailutils/list.h> 25 #include <list0.h>
26
27 #include <iterator0.h> 26 #include <iterator0.h>
28 27
29 int 28 int
...@@ -36,6 +35,10 @@ iterator_create (iterator_t *piterator, list_t list) ...@@ -36,6 +35,10 @@ iterator_create (iterator_t *piterator, list_t list)
36 if (iterator == NULL) 35 if (iterator == NULL)
37 return ENOMEM; 36 return ENOMEM;
38 iterator->list = list; 37 iterator->list = list;
38 iterator->cur = NULL;
39 iterator->next = list->itr;
40 list->itr = iterator;
41 iterator->is_advanced = 0;
39 *piterator = iterator; 42 *piterator = iterator;
40 return 0; 43 return 0;
41 } 44 }
...@@ -43,9 +46,24 @@ iterator_create (iterator_t *piterator, list_t list) ...@@ -43,9 +46,24 @@ iterator_create (iterator_t *piterator, list_t list)
43 void 46 void
44 iterator_destroy (iterator_t *piterator) 47 iterator_destroy (iterator_t *piterator)
45 { 48 {
46 if (piterator && *piterator) 49 iterator_t itr, prev;
50
51 if (!piterator || !*piterator)
52 return;
53
54 for (itr = (*piterator)->list->itr, prev = NULL;
55 itr;
56 prev = itr, itr = itr->next)
57 if (*piterator == itr)
58 break;
59
60 if (itr)
47 { 61 {
48 free (*piterator); 62 if (prev)
63 prev->next = itr->next;
64 else
65 itr->list->itr = itr->next;
66 free(itr);
49 *piterator = NULL; 67 *piterator = NULL;
50 } 68 }
51 } 69 }
...@@ -53,32 +71,55 @@ iterator_destroy (iterator_t *piterator) ...@@ -53,32 +71,55 @@ iterator_destroy (iterator_t *piterator)
53 int 71 int
54 iterator_first (iterator_t iterator) 72 iterator_first (iterator_t iterator)
55 { 73 {
56 iterator->index = 0; 74 iterator->cur = iterator->list->head.next;
75 iterator->is_advanced = 0;
57 return 0; 76 return 0;
58 } 77 }
59 78
60 int 79 int
61 iterator_next (iterator_t iterator) 80 iterator_next (iterator_t iterator)
62 { 81 {
63 iterator->index++; 82 if (!iterator->is_advanced)
83 iterator->cur = iterator->cur->next;
84 iterator->is_advanced = 0;
64 return 0; 85 return 0;
65 } 86 }
66 87
67 int 88 int
68 iterator_current (iterator_t iterator, void **pitem) 89 iterator_current (iterator_t iterator, void **pitem)
69 { 90 {
70 return list_get (iterator->list, iterator->index, pitem); 91 if (!iterator->cur)
92 return ENOENT;
93 *pitem = iterator->cur->item;
94 return 0;
71 } 95 }
72 96
73 int 97 int
74 iterator_is_done (iterator_t iterator) 98 iterator_is_done (iterator_t iterator)
75 { 99 {
76 size_t count;
77 int status;
78 if (iterator == NULL) 100 if (iterator == NULL)
79 return 1; 101 return 1;
80 status = list_count (iterator->list, &count); 102 return iterator->cur == NULL || iterator->cur == &iterator->list->head;
81 if (status != 0) 103 }
82 return 1; 104
83 return (iterator->index >= count); 105 int
106 iterator_get_list (iterator_t iterator, list_t *plist)
107 {
108 if (!iterator)
109 return EINVAL;
110 *plist = iterator->list;
111 return NULL;
112 }
113
114 void
115 iterator_advance (iterator_t iterator, struct list_data *e)
116 {
117 for (; iterator; iterator = iterator->next)
118 {
119 if (iterator->cur == e)
120 {
121 iterator->cur = e->next;
122 iterator->is_advanced++;
123 }
124 }
84 } 125 }
......