1 Return-Path: <bremner@tesseract.cs.unb.ca>
\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 arlo.cworth.org (Postfix) with ESMTP id D1C466DE00B8
\r
6 for <notmuch@notmuchmail.org>; Tue, 2 Aug 2016 21:40:39 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org
\r
11 X-Spam-Status: No, score=-0.005 tagged_above=-999 required=5
\r
12 tests=[AWL=-0.006, HEADER_FROM_DIFFERENT_DOMAINS=0.001]
\r
14 Received: from arlo.cworth.org ([127.0.0.1])
\r
15 by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id pNAI9-Byhq3I for <notmuch@notmuchmail.org>;
\r
17 Tue, 2 Aug 2016 21:40:31 -0700 (PDT)
\r
18 Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197])
\r
19 by arlo.cworth.org (Postfix) with ESMTPS id DA7566DE092A
\r
20 for <notmuch@notmuchmail.org>; Tue, 2 Aug 2016 21:39:07 -0700 (PDT)
\r
21 Received: from remotemail by fethera.tethera.net with local (Exim 4.84_2)
\r
22 (envelope-from <bremner@tesseract.cs.unb.ca>)
\r
23 id 1bUnxk-0000Hw-3h; Wed, 03 Aug 2016 00:39:24 -0400
\r
24 Received: (nullmailer pid 12781 invoked by uid 1000);
\r
25 Wed, 03 Aug 2016 00:30:32 -0000
\r
26 From: David Bremner <david@tethera.net>
\r
27 To: notmuch@notmuchmail.org
\r
28 Subject: [PATCH 2/8] lib: private string map (associative array) API
\r
29 Date: Wed, 3 Aug 2016 09:30:22 +0900
\r
30 Message-Id: <1470184228-12517-3-git-send-email-david@tethera.net>
\r
31 X-Mailer: git-send-email 2.8.1
\r
32 In-Reply-To: <1470184228-12517-1-git-send-email-david@tethera.net>
\r
33 References: <1470184228-12517-1-git-send-email-david@tethera.net>
\r
35 Content-Type: text/plain; charset=UTF-8
\r
36 Content-Transfer-Encoding: 8bit
\r
37 X-BeenThere: notmuch@notmuchmail.org
\r
38 X-Mailman-Version: 2.1.20
\r
40 List-Id: "Use and development of the notmuch mail system."
\r
41 <notmuch.notmuchmail.org>
\r
42 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,
\r
43 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
44 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>
\r
45 List-Post: <mailto:notmuch@notmuchmail.org>
\r
46 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
47 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,
\r
48 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
49 X-List-Received-Date: Wed, 03 Aug 2016 04:40:39 -0000
\r
51 The choice of array implementation is deliberate, for future iterator support
\r
53 lib/Makefile.local | 2 +
\r
54 lib/notmuch-private.h | 11 ++++
\r
55 lib/string-map.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++
\r
56 3 files changed, 166 insertions(+)
\r
57 create mode 100644 lib/string-map.c
\r
59 diff --git a/lib/Makefile.local b/lib/Makefile.local
\r
60 index beb9635..c012ed1 100644
\r
61 --- a/lib/Makefile.local
\r
62 +++ b/lib/Makefile.local
\r
63 @@ -40,6 +40,7 @@ libnotmuch_c_srcs = \
\r
66 $(dir)/built-with.c \
\r
67 + $(dir)/string-map.c \
\r
70 libnotmuch_cxx_srcs = \
\r
71 @@ -48,6 +49,7 @@ libnotmuch_cxx_srcs = \
\r
72 $(dir)/directory.cc \
\r
75 + $(dir)/message-property.cc \
\r
77 $(dir)/query-fp.cc \
\r
79 diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
\r
80 index df63905..5abde88 100644
\r
81 --- a/lib/notmuch-private.h
\r
82 +++ b/lib/notmuch-private.h
\r
83 @@ -540,6 +540,17 @@ _notmuch_string_list_sort (notmuch_string_list_t *list);
\r
85 typedef struct _notmuch_string_map notmuch_string_map_t;
\r
87 +notmuch_string_map_t *
\r
88 +_notmuch_string_map_create (const void *ctx);
\r
91 +_notmuch_string_map_append (notmuch_string_map_t *map,
\r
93 + const char *value);
\r
96 +_notmuch_string_map_get (notmuch_string_map_t *map, const char *key);
\r
101 diff --git a/lib/string-map.c b/lib/string-map.c
\r
102 new file mode 100644
\r
103 index 0000000..0491a10
\r
105 +++ b/lib/string-map.c
\r
107 +/* string-map.c - associative arrays of strings
\r
110 + * Copyright © 2016 David Bremner
\r
112 + * This program is free software: you can redistribute it and/or modify
\r
113 + * it under the terms of the GNU General Public License as published by
\r
114 + * the Free Software Foundation, either version 3 of the License, or
\r
115 + * (at your option) any later version.
\r
117 + * This program is distributed in the hope that it will be useful,
\r
118 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
119 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
120 + * GNU General Public License for more details.
\r
122 + * You should have received a copy of the GNU General Public License
\r
123 + * along with this program. If not, see http://www.gnu.org/licenses/ .
\r
125 + * Author: David Bremner <david@tethera.net>
\r
128 +#include "notmuch-private.h"
\r
130 +/* Create a new notmuch_string_map_t object, with 'ctx' as its
\r
133 + * This function can return NULL in case of out-of-memory.
\r
136 +typedef struct _notmuch_string_pair_t {
\r
139 +} notmuch_string_pair_t;
\r
141 +struct _notmuch_string_map {
\r
142 + notmuch_bool_t sorted;
\r
144 + notmuch_string_pair_t *pairs;
\r
147 +notmuch_string_map_t *
\r
148 +_notmuch_string_map_create (const void *ctx)
\r
150 + notmuch_string_map_t *map;
\r
152 + map = talloc (ctx, notmuch_string_map_t);
\r
153 + if (unlikely (map == NULL))
\r
157 + map->pairs = NULL;
\r
158 + map->sorted = TRUE;
\r
164 +_notmuch_string_map_append (notmuch_string_map_t *map,
\r
166 + const char *value)
\r
170 + map->sorted = FALSE;
\r
173 + map->pairs = talloc_realloc (map, map->pairs, notmuch_string_pair_t, map->length + 1);
\r
175 + map->pairs = talloc_array (map, notmuch_string_pair_t, map->length + 1);
\r
177 + map->pairs[map->length - 1].key = talloc_strdup (map, key);
\r
178 + map->pairs[map->length - 1].value = talloc_strdup (map, value);
\r
180 + /* Add sentinel */
\r
181 + map->pairs[map->length].key = NULL;
\r
182 + map->pairs[map->length].value = NULL;
\r
187 +cmppair (const void *pa, const void *pb)
\r
189 + notmuch_string_pair_t *a = (notmuch_string_pair_t *) pa;
\r
190 + notmuch_string_pair_t *b = (notmuch_string_pair_t *) pb;
\r
192 + return strcmp (a->key, b->key);
\r
196 +_notmuch_string_map_sort (notmuch_string_map_t *map)
\r
198 + if (map->length == 0)
\r
204 + qsort (map->pairs, map->length, sizeof (notmuch_string_pair_t), cmppair);
\r
206 + map->sorted = TRUE;
\r
209 +static notmuch_bool_t
\r
210 +string_cmp (const char *a, const char *b, notmuch_bool_t exact)
\r
213 + return (strcmp (a, b));
\r
215 + return (strncmp (a, b, strlen (a)));
\r
218 +static notmuch_string_pair_t *
\r
219 +bsearch_first (notmuch_string_pair_t *array, size_t len, const char *key, notmuch_bool_t exact)
\r
221 + size_t first = 0;
\r
222 + size_t last = len - 1;
\r
228 + while (last > first) {
\r
229 + mid = (first + last) / 2;
\r
230 + int sign = string_cmp (key, array[mid].key, exact);
\r
239 + if (string_cmp (key, array[first].key, exact) == 0)
\r
240 + return array + first;
\r
247 +_notmuch_string_map_get (notmuch_string_map_t *map, const char *key)
\r
249 + notmuch_string_pair_t *pair;
\r
251 + /* this means that calling append invalidates iterators */
\r
252 + _notmuch_string_map_sort (map);
\r
254 + pair = bsearch_first (map->pairs, map->length, key, TRUE);
\r
258 + return pair->value;
\r