1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2010 Index Data
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 static void dict_del_subtree(Dict dict, Dict_ptr ptr,
29 int (*f)(const char *, void *))
38 dict_bf_readp(dict->dbf, ptr, &p);
39 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
41 for (i = 0; i <= hi; i++)
45 /* string (Dict_char *) DICT_EOS terminated */
46 /* unsigned char length of information */
47 /* char * information */
48 char *info = (char*)p + indxp[-i];
50 (*f)(info + (dict_strlen((Dict_char*) info)+1)
51 *sizeof(Dict_char), client);
58 /* Dict_char sub char */
59 /* unsigned char length of information */
60 /* char * information */
61 char *info = (char*)p - indxp[-i];
62 memcpy(&subptr, info, sizeof(Dict_ptr));
64 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
67 (*f)(info+sizeof(Dict_ptr)+sizeof(Dict_char), client);
71 dict_del_subtree(dict, subptr, client, f);
73 /* page may be gone. reread it .. */
74 dict_bf_readp(dict->dbf, ptr, &p);
75 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
79 DICT_backptr(p) = dict->head.freelist;
80 dict->head.freelist = ptr;
81 dict_bf_touch(dict->dbf, ptr);
84 static int dict_del_string(Dict dict, const Dict_char *str, Dict_ptr ptr,
85 int sub_flag, void *client,
86 int (*f)(const char *, void *))
98 dict_bf_readp(dict->dbf, ptr, &p);
100 hi = DICT_nodir(p)-1;
101 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
107 /* string (Dict_char *) DICT_EOS terminated */
108 /* unsigned char length of information */
109 /* char * information */
110 info = (char*)p + indxp[-mid];
112 cmp = dict_strcmp((Dict_char*) info, str);
115 /* determine if prefix match */
116 if (!dict_strncmp(str, (Dict_char*) info, dict_strlen(str)))
119 (*f)(info + (dict_strlen((Dict_char*) info)+1)
120 *sizeof(Dict_char), client);
122 hi = DICT_nodir(p)-1;
125 indxp[-mid] = indxp[-mid-1];
130 dict_bf_touch(dict->dbf, ptr);
133 r = 1; /* signal deleted */
134 /* start again (may not be the most efficient way to go)*/
140 /* normal delete: delete if equal */
143 hi = DICT_nodir(p)-1;
146 indxp[-mid] = indxp[-mid-1];
151 dict_bf_touch(dict->dbf, ptr);
161 /* Dict_ptr subptr */
162 /* Dict_char sub char */
163 /* unsigned char length of information */
164 /* char * information */
165 info = (char*)p - indxp[-mid];
166 memcpy(&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
170 memcpy(&subptr, info, sizeof(Dict_ptr));
171 if (*++str == DICT_EOS)
173 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
175 /* entry does exist. Wipe it out */
176 info[sizeof(Dict_ptr)+sizeof(Dict_char)] = 0;
178 dict_bf_touch(dict->dbf, ptr);
181 (*f)(info+sizeof(Dict_ptr)+sizeof(Dict_char),
187 /* must delete all suffixes (subtrees) as well */
188 hi = DICT_nodir(p)-1;
191 indxp[-mid] = indxp[-mid-1];
196 dict_bf_touch(dict->dbf, ptr);
201 /* subptr may be 0 */
202 r = dict_del_string(dict, str, subptr, sub_flag, client, f);
205 dict_bf_readp(dict->dbf, ptr, &p);
207 ((char*) p+DICT_bsize(p)-sizeof(short));
208 info = (char*)p - indxp[-mid];
211 { /* subptr page is empty and already removed */
212 hi = DICT_nodir(p)-1;
215 indxp[-mid] = indxp[-mid-1];
219 dict_bf_touch(dict->dbf, ptr);
222 subptr = 0; /* prevent dict_del_subtree (below) */
232 if (DICT_nodir(p) == 0 && ptr != dict->head.root)
234 DICT_backptr(p) = dict->head.freelist;
235 dict->head.freelist = ptr;
236 dict_bf_touch(dict->dbf, ptr);
239 if (subptr && sub_flag)
240 dict_del_subtree(dict, subptr, client, f);
245 int dict_delete(Dict dict, const char *p)
247 return dict_del_string(dict, (const Dict_char*) p, dict->head.root, 0,
251 int dict_delete_subtree(Dict dict, const char *p, void *client,
252 int (*f)(const char *info, void *client))
254 return dict_del_string(dict, (const Dict_char*) p, dict->head.root, 1,
260 * c-file-style: "Stroustrup"
261 * indent-tabs-mode: nil
263 * vim: shiftwidth=4 tabstop=8 expandtab