2 * Copyright (C) 2003-2009 The Music Player Daemon Project
3 * http://www.musicpd.org
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 2 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #define NUM_SLOTS 16384
29 struct strset_slot
*next
;
36 struct strset_slot
*current_slot
;
39 struct strset_slot slots
[NUM_SLOTS
];
42 static unsigned calc_hash(const char *p
) {
48 hash
= (hash
<< 5) + hash
+ *p
++;
53 G_GNUC_MALLOC
struct strset
*strset_new(void)
55 struct strset
*set
= g_new0(struct strset
, 1);
59 void strset_free(struct strset
*set
)
63 for (i
= 0; i
< NUM_SLOTS
; ++i
) {
64 struct strset_slot
*slot
= set
->slots
[i
].next
, *next
;
66 while (slot
!= NULL
) {
76 void strset_add(struct strset
*set
, const char *value
)
78 struct strset_slot
*base_slot
79 = &set
->slots
[calc_hash(value
) % NUM_SLOTS
];
80 struct strset_slot
*slot
= base_slot
;
82 if (base_slot
->value
== NULL
) {
83 /* empty slot - put into base_slot */
84 assert(base_slot
->next
== NULL
);
86 base_slot
->value
= value
;
91 for (slot
= base_slot
; slot
!= NULL
; slot
= slot
->next
)
92 if (strcmp(slot
->value
, value
) == 0)
93 /* found it - do nothing */
96 /* insert it into the slot chain */
97 slot
= g_new(struct strset_slot
, 1);
98 slot
->next
= base_slot
->next
;
100 base_slot
->next
= slot
;
104 int strset_get(const struct strset
*set
, const char *value
)
106 const struct strset_slot
*slot
= &set
->slots
[calc_hash(value
)];
108 if (slot
->value
== NULL
)
111 for (slot
= slot
->next
; slot
!= NULL
; slot
= slot
->next
)
112 if (strcmp(slot
->value
, value
) == 0)
113 /* found it - do nothing */
119 unsigned strset_size(const struct strset
*set
)
124 void strset_rewind(struct strset
*set
)
126 set
->current_slot
= NULL
;
130 const char *strset_next(struct strset
*set
)
132 if (set
->current_slot
!= NULL
&& set
->current_slot
->next
!= NULL
) {
133 set
->current_slot
= set
->current_slot
->next
;
134 return set
->current_slot
->value
;
137 while (set
->next_slot
< NUM_SLOTS
&&
138 set
->slots
[set
->next_slot
].value
== NULL
)
141 if (set
->next_slot
>= NUM_SLOTS
)
144 set
->current_slot
= &set
->slots
[set
->next_slot
++];
145 return set
->current_slot
->value
;