Re: [PATCH 0/4] Allow specifying alternate names for addresses in other_email
[notmuch-archives.git] / d8 / 1a88342fb96169188abb8a726d52ad28624845
1 Return-Path: <meskio@sindominio.net>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id F2A6E431FC1\r
6         for <notmuch@notmuchmail.org>; Sat, 20 Mar 2010 03:21:50 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -1.9\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5\r
12         tests=[BAYES_00=-1.9] autolearn=ham\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id bFeKf-mL5SPx for <notmuch@notmuchmail.org>;\r
16         Sat, 20 Mar 2010 03:21:49 -0700 (PDT)\r
17 Received: from flatline.sindominio.net (flatline.sindominio.net [82.144.4.26])\r
18         by olra.theworths.org (Postfix) with ESMTP id 19C2D414BB9\r
19         for <notmuch@notmuchmail.org>; Sat, 20 Mar 2010 03:21:48 -0700 (PDT)\r
20 Received: from localhost (localhost.localdomain [127.0.0.1])\r
21         by flatline.sindominio.net (Postfix) with ESMTP id 51FEE262E3F;\r
22         Sat, 20 Mar 2010 11:21:47 +0100 (CET)\r
23 X-Virus-Scanned: Debian amavisd-new at sindominio.net\r
24 Received: from flatline.sindominio.net ([127.0.0.1])\r
25         by localhost (flatline.sindominio.net [127.0.0.1]) (amavisd-new,\r
26         port 10024)\r
27         with ESMTP id dEDiqtirI3iO; Sat, 20 Mar 2010 11:21:44 +0100 (CET)\r
28 Received: from blackspot (heal.cauterized.net [89.140.131.167])\r
29         by flatline.sindominio.net (Postfix) with ESMTPA id 505D9262E3D;\r
30         Sat, 20 Mar 2010 11:21:33 +0100 (CET)\r
31 Received: by blackspot (Postfix, from userid 1000)\r
32         id 79F598BDFE; Sat, 20 Mar 2010 11:24:54 +0100 (CET)\r
33 From: Ruben Pollan <meskio@sindominio.net>\r
34 To: notmuch@notmuchmail.org\r
35 Date: Sat, 20 Mar 2010 11:23:24 +0100\r
36 Message-Id: <1269080605-5617-5-git-send-email-meskio@sindominio.net>\r
37 X-Mailer: git-send-email 1.7.0\r
38 In-Reply-To: <873a09jt2t.fsf@yoom.home.cworth.org>\r
39 References: <873a09jt2t.fsf@yoom.home.cworth.org>\r
40 Subject: [notmuch] [PATCH 4/5] Added backwards iterator to threads\r
41 X-BeenThere: notmuch@notmuchmail.org\r
42 X-Mailman-Version: 2.1.13\r
43 Precedence: list\r
44 List-Id: "Use and development of the notmuch mail system."\r
45         <notmuch.notmuchmail.org>\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
47         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
49 List-Post: <mailto:notmuch@notmuchmail.org>\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
53 X-List-Received-Date: Sat, 20 Mar 2010 10:21:51 -0000\r
54 \r
55 Added the functions notmuch_threads_move_to_prevoius,\r
56 notmuch_threads_move_to_last and  notmuch_threads_move_to_first to\r
57 notmuch library. With them is possible to iterate backwards on threads.\r
58 \r
59 * notmuch_threads_move_to_prevoius do the opposite than\r
60   notmuch_threads_move_to_next, getting the threads iterator one\r
61   position backwards.\r
62 \r
63 * notmuch_threads_move_to_last move the iterator to the first last thread.\r
64 \r
65 * notmuch_threads_move_to_first move the iterator to the first valid\r
66   thread.\r
67 \r
68 For it has been implemented notmuch_thread_list_t structur that stores\r
69 the thread_ids so the backwards iteration gets the thread_id in the same\r
70 order that was show on forward iteration.\r
71 ---\r
72  lib/notmuch.h |   28 +++++++++++\r
73  lib/query.cc  |  143 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----\r
74  2 files changed, 159 insertions(+), 12 deletions(-)\r
75 \r
76 diff --git a/lib/notmuch.h b/lib/notmuch.h\r
77 index 753f3bb..b96b624 100644\r
78 --- a/lib/notmuch.h\r
79 +++ b/lib/notmuch.h\r
80 @@ -466,6 +466,15 @@ notmuch_threads_valid (notmuch_threads_t *threads);\r
81  notmuch_thread_t *\r
82  notmuch_threads_get (notmuch_threads_t *threads);\r
83  \r
84 +/* Move the 'threads' iterator to the first thread.\r
85 + *\r
86 + * After that the 'threads' iterator will be set to the first valid \r
87 + * thread, so it can be use to iterate with \r
88 + * notmuch_threads_move_to_next.\r
89 + */\r
90 +void\r
91 +notmuch_threads_move_to_first (notmuch_threads_t *threads);\r
92 +\r
93  /* Move the 'threads' iterator to the next thread.\r
94   *\r
95   * If 'threads' is already pointing at the last thread then the\r
96 @@ -479,6 +488,25 @@ notmuch_threads_get (notmuch_threads_t *threads);\r
97  void\r
98  notmuch_threads_move_to_next (notmuch_threads_t *threads);\r
99  \r
100 +/* Move the 'threads' iterator to the last thread.\r
101 + *\r
102 + * After that the 'threads' iterator will be set to the last valid \r
103 + * thread, so it can be use to iterate with \r
104 + * notmuch_threads_move_to_previous.\r
105 + */\r
106 +void\r
107 +notmuch_threads_move_to_last (notmuch_threads_t *threads);\r
108 +\r
109 +/* Move the 'threads' iterator to the previous thread.\r
110 + *\r
111 + * If 'threads' is already pointing at the first thread then the\r
112 + * iterator will be moved to a point just beyond that first thread,\r
113 + * (where notmuch_threads_valid will return FALSE and\r
114 + * notmuch_threads_get will return NULL).\r
115 + */\r
116 +void\r
117 +notmuch_threads_move_to_previous (notmuch_threads_t *threads);\r
118 +\r
119  /* Destroy a notmuch_threads_t object.\r
120   *\r
121   * It's not strictly necessary to call this function. All memory from\r
122 diff --git a/lib/query.cc b/lib/query.cc\r
123 index 44950c1..39985e7 100644\r
124 --- a/lib/query.cc\r
125 +++ b/lib/query.cc\r
126 @@ -39,13 +39,25 @@ typedef struct _notmuch_mset_messages {\r
127      Xapian::MSetIterator iterator_end;\r
128  } notmuch_mset_messages_t;\r
129  \r
130 +typedef struct _notmuch_thread_node {\r
131 +    const char *thread_id;\r
132 +    struct _notmuch_thread_node *next;\r
133 +    struct _notmuch_thread_node *prev;\r
134 +} notmuch_thread_node_t;\r
135 +\r
136 +typedef struct _notmuch_thread_list {\r
137 +    notmuch_thread_node_t *head;\r
138 +    notmuch_thread_node_t *tail;\r
139 +    notmuch_thread_node_t *iterator;\r
140 +} notmuch_thread_list_t;\r
141 +\r
142  struct _notmuch_threads {\r
143      notmuch_query_t *query;\r
144      GHashTable *threads;\r
145      notmuch_messages_t *messages;\r
146  \r
147 -    /* This thread ID is our iterator state. */\r
148 -    const char *thread_id;\r
149 +    /* thread list with the thread_id of the showed messages */\r
150 +    notmuch_thread_list_t *list;\r
151  };\r
152  \r
153  notmuch_query_t *\r
154 @@ -269,6 +281,64 @@ _notmuch_mset_messages_move_to_previous (notmuch_messages_t *messages)\r
155      }\r
156  }\r
157  \r
158 +static void\r
159 +_notmuch_thread_list_create (notmuch_thread_list_t *list, const char *thread_id)\r
160 +{\r
161 +    list->head = talloc (list, notmuch_thread_node_t);\r
162 +    list->tail = list->head;\r
163 +    list->iterator = list->head;\r
164 +    list->iterator->thread_id = thread_id;\r
165 +    list->iterator->next = NULL;\r
166 +    list->iterator->prev = NULL;\r
167 +}\r
168 +\r
169 +static void\r
170 +_notmuch_thread_list_append (notmuch_thread_list_t *list, const char *thread_id)\r
171 +{\r
172 +    list->tail->next = talloc (list, notmuch_thread_node_t);\r
173 +    list->iterator = list->tail->next;\r
174 +    list->iterator->thread_id = thread_id;\r
175 +    list->iterator->next = NULL;\r
176 +    list->iterator->prev = list->tail;\r
177 +    list->tail = list->iterator;\r
178 +}\r
179 +\r
180 +static const char *\r
181 +_notmuch_thread_list_get_id (notmuch_thread_list_t *list)\r
182 +{\r
183 +    return list->iterator->thread_id;\r
184 +}\r
185 +\r
186 +static notmuch_bool_t\r
187 +_notmuch_thread_list_valid (notmuch_thread_list_t *list)\r
188 +{\r
189 +    return (list->iterator != NULL);\r
190 +}\r
191 +\r
192 +static void\r
193 +_notmuch_thread_list_move_to_first (notmuch_thread_list_t *list)\r
194 +{\r
195 +    list->iterator = list->head;\r
196 +}\r
197 +\r
198 +static void\r
199 +_notmuch_thread_list_move_to_next (notmuch_thread_list_t *list)\r
200 +{\r
201 +    list->iterator = list->iterator->next;\r
202 +}\r
203 +\r
204 +static void\r
205 +_notmuch_thread_list_move_to_last (notmuch_thread_list_t *list)\r
206 +{\r
207 +    list->iterator = list->tail;\r
208 +}\r
209 +\r
210 +static void\r
211 +_notmuch_thread_list_move_to_previous (notmuch_thread_list_t *list)\r
212 +{\r
213 +    list->iterator = list->iterator->prev;\r
214 +}\r
215 +\r
216  /* Glib objects force use to use a talloc destructor as well, (but not\r
217   * nearly as ugly as the for messages due to C++ objects). At\r
218   * this point, I'd really like to have some talloc-friendly\r
219 @@ -297,10 +367,13 @@ notmuch_query_search_threads (notmuch_query_t *query)\r
220  \r
221      threads->messages = notmuch_query_search_messages (query);\r
222  \r
223 +    threads->list = talloc (threads, notmuch_thread_list_t);\r
224      message = notmuch_messages_get (threads->messages);\r
225 -    threads->thread_id = notmuch_message_get_thread_id (message);\r
226 +    _notmuch_thread_list_create (threads->list,\r
227 +                                  notmuch_message_get_thread_id (message));\r
228      g_hash_table_insert (threads->threads,\r
229 -                         xstrdup (threads->thread_id), NULL);\r
230 +                         xstrdup (_notmuch_thread_list_get_id (threads->list)),\r
231 +                         NULL);\r
232  \r
233      talloc_set_destructor (threads, _notmuch_threads_destructor);\r
234  \r
235 @@ -316,7 +389,7 @@ notmuch_query_destroy (notmuch_query_t *query)\r
236  notmuch_bool_t\r
237  notmuch_threads_valid (notmuch_threads_t *threads)\r
238  {\r
239 -    return (threads->thread_id != NULL);\r
240 +    return _notmuch_thread_list_valid (threads->list);\r
241  }\r
242  \r
243  notmuch_thread_t *\r
244 @@ -327,37 +400,83 @@ notmuch_threads_get (notmuch_threads_t *threads)\r
245  \r
246      return _notmuch_thread_create (threads->query,\r
247                                    threads->query->notmuch,\r
248 -                                  threads->thread_id,\r
249 +                                  _notmuch_thread_list_get_id (threads->list),\r
250                                    threads->query->query_string);\r
251  }\r
252  \r
253  void\r
254 +notmuch_threads_move_to_first (notmuch_threads_t *threads)\r
255 +{\r
256 +    _notmuch_thread_list_move_to_first (threads->list);\r
257 +}\r
258 +\r
259 +void\r
260  notmuch_threads_move_to_next (notmuch_threads_t *threads)\r
261  {\r
262 -    notmuch_message_t *message;\r
263 +    if (!_notmuch_thread_list_valid (threads->list))\r
264 +        return;\r
265 +\r
266 +    _notmuch_thread_list_move_to_next (threads->list);\r
267 +    if (_notmuch_thread_list_valid (threads->list))\r
268 +        return;\r
269  \r
270      while (notmuch_messages_valid (threads->messages))\r
271      {\r
272 -       message = notmuch_messages_get (threads->messages);\r
273 +        notmuch_message_t *message;\r
274 +        const char *thread_id;\r
275  \r
276 -       threads->thread_id = notmuch_message_get_thread_id (message);\r
277 +       message = notmuch_messages_get (threads->messages);\r
278 +       thread_id = notmuch_message_get_thread_id (message);\r
279  \r
280         if (! g_hash_table_lookup_extended (threads->threads,\r
281 -                                           threads->thread_id,\r
282 +                                           thread_id,\r
283                                             NULL, NULL))\r
284         {\r
285             g_hash_table_insert (threads->threads,\r
286 -                                xstrdup (threads->thread_id), NULL);\r
287 +                                xstrdup (thread_id), NULL);\r
288 +            _notmuch_thread_list_append (threads->list, thread_id);\r
289             notmuch_messages_move_to_next (threads->messages);\r
290             return;\r
291         }\r
292  \r
293         notmuch_messages_move_to_next (threads->messages);\r
294      }\r
295 +}\r
296 +\r
297 +void\r
298 +notmuch_threads_move_to_last (notmuch_threads_t *threads)\r
299 +{\r
300 +    _notmuch_thread_list_move_to_last (threads->list);\r
301 +\r
302 +    while (notmuch_messages_valid (threads->messages))\r
303 +    {\r
304 +        notmuch_message_t *message;\r
305 +        const char *thread_id;\r
306 +\r
307 +       message = notmuch_messages_get (threads->messages);\r
308 +       thread_id = notmuch_message_get_thread_id (message);\r
309 +\r
310 +       if (! g_hash_table_lookup_extended (threads->threads,\r
311 +                                           thread_id,\r
312 +                                           NULL, NULL))\r
313 +       {\r
314 +           g_hash_table_insert (threads->threads,\r
315 +                                xstrdup (thread_id), NULL);\r
316 +            _notmuch_thread_list_append (threads->list, thread_id);\r
317 +        }\r
318  \r
319 -    threads->thread_id = NULL;\r
320 +       notmuch_messages_move_to_next (threads->messages);\r
321 +    }\r
322  }\r
323  \r
324 +void\r
325 +notmuch_threads_move_to_previous (notmuch_threads_t *threads)\r
326 +{\r
327 +    if (!_notmuch_thread_list_valid (threads->list))\r
328 +        return;\r
329 +\r
330 +    _notmuch_thread_list_move_to_previous (threads->list);\r
331 +}\r
332  \r
333  void\r
334  notmuch_threads_destroy (notmuch_threads_t *threads)\r
335 -- \r
336 1.7.0\r
337 \r