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/>.
20 #include <sys/types.h>
29 ms_init(ms a
, ms_event_fn oninsert
, ms_event_fn onremove
)
31 a
->used
= a
->cap
= a
->last
= 0;
33 a
->oninsert
= oninsert
;
34 a
->onremove
= onremove
;
41 size_t ncap
= (a
->cap
<< 1) ? : 1;
43 nitems
= malloc(ncap
* sizeof(void *));
46 memcpy(nitems
, a
->items
, a
->used
* sizeof(void *));
53 ms_append(ms a
, void *item
)
55 if (a
->used
>= a
->cap
) grow(a
);
56 if (a
->used
>= a
->cap
) return 0;
58 a
->items
[a
->used
++] = item
;
59 if (a
->oninsert
) a
->oninsert(a
, item
, a
->used
- 1);
64 ms_delete(ms a
, size_t i
)
68 if (i
>= a
->used
) return 0;
70 a
->items
[i
] = a
->items
[--a
->used
];
72 /* it has already been removed now */
73 if (a
->onremove
) a
->onremove(a
, item
, i
);
80 while (ms_delete(a
, 0));
82 ms_init(a
, a
->oninsert
, a
->onremove
);
86 ms_remove(ms a
, void *item
)
90 for (i
= 0; i
< a
->used
; i
++) {
91 if (a
->items
[i
] == item
) return ms_delete(a
, i
);
97 ms_contains(ms a
, void *item
)
101 for (i
= 0; i
< a
->used
; i
++) {
102 if (a
->items
[i
] == item
) return 1;
112 if (!a
->used
) return NULL
;
114 a
->last
= a
->last
% a
->used
;
115 item
= a
->items
[a
->last
];
116 ms_delete(a
, a
->last
);