update to newest ct; fixes #60
[beanstalkd.git] / ms.c
blobf703a40591829bd746a3898e4725ea9870443c69
1 /* ms.c - resizable multiset implementation */
3 /* Copyright (C) 2008 Keith Rarick and Philotic Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <stdint.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include "dat.h"
24 void
25 ms_init(ms a, ms_event_fn oninsert, ms_event_fn onremove)
27 a->used = a->cap = a->last = 0;
28 a->items = NULL;
29 a->oninsert = oninsert;
30 a->onremove = onremove;
33 static void
34 grow(ms a)
36 void **nitems;
37 size_t ncap = (a->cap << 1) ? : 1;
39 nitems = malloc(ncap * sizeof(void *));
40 if (!nitems) return;
42 memcpy(nitems, a->items, a->used * sizeof(void *));
43 free(a->items);
44 a->items = nitems;
45 a->cap = ncap;
48 int
49 ms_append(ms a, void *item)
51 if (a->used >= a->cap) grow(a);
52 if (a->used >= a->cap) return 0;
54 a->items[a->used++] = item;
55 if (a->oninsert) a->oninsert(a, item, a->used - 1);
56 return 1;
59 static int
60 ms_delete(ms a, size_t i)
62 void *item;
64 if (i >= a->used) return 0;
65 item = a->items[i];
66 a->items[i] = a->items[--a->used];
68 /* it has already been removed now */
69 if (a->onremove) a->onremove(a, item, i);
70 return 1;
73 void
74 ms_clear(ms a)
76 while (ms_delete(a, 0));
77 free(a->items);
78 ms_init(a, a->oninsert, a->onremove);
81 int
82 ms_remove(ms a, void *item)
84 size_t i;
86 for (i = 0; i < a->used; i++) {
87 if (a->items[i] == item) return ms_delete(a, i);
89 return 0;
92 int
93 ms_contains(ms a, void *item)
95 size_t i;
97 for (i = 0; i < a->used; i++) {
98 if (a->items[i] == item) return 1;
100 return 0;
103 void *
104 ms_take(ms a)
106 void *item;
108 if (!a->used) return NULL;
110 a->last = a->last % a->used;
111 item = a->items[a->last];
112 ms_delete(a, a->last);
113 ++a->last;
114 return item;