1 /* This file is part of the Zebra server.
2 Copyright (C) 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
30 static void dict_del_subtree(Dict dict, Dict_ptr ptr,
32 int (*f)(const char *, void *))
41 dict_bf_readp(dict->dbf, ptr, &p);
42 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
44 for (i = 0; i <= hi; i++)
48 /* string (Dict_char *) DICT_EOS terminated */
49 /* unsigned char length of information */
50 /* char * information */
51 char *info = (char*)p + indxp[-i];
53 (*f)(info + (dict_strlen((Dict_char*) info)+1)
54 *sizeof(Dict_char), client);
61 /* Dict_char sub char */
62 /* unsigned char length of information */
63 /* char * information */
64 char *info = (char*)p - indxp[-i];
65 memcpy(&subptr, info, sizeof(Dict_ptr));
67 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
70 (*f)(info+sizeof(Dict_ptr)+sizeof(Dict_char), client);
74 dict_del_subtree(dict, subptr, client, f);
76 /* page may be gone. reread it .. */
77 dict_bf_readp(dict->dbf, ptr, &p);
78 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
82 DICT_backptr(p) = dict->head.freelist;
83 dict->head.freelist = ptr;
84 dict_bf_touch(dict->dbf, ptr);
87 static int dict_del_string(Dict dict, const Dict_char *str, Dict_ptr ptr,
88 int sub_flag, void *client,
89 int (*f)(const char *, void *))
101 dict_bf_readp(dict->dbf, ptr, &p);
103 hi = DICT_nodir(p)-1;
104 indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
110 /* string (Dict_char *) DICT_EOS terminated */
111 /* unsigned char length of information */
112 /* char * information */
113 info = (char*)p + indxp[-mid];
115 cmp = dict_strcmp((Dict_char*) info, str);
118 /* determine if prefix match */
119 if (!dict_strncmp(str, (Dict_char*) info, dict_strlen(str)))
122 (*f)(info + (dict_strlen((Dict_char*) info)+1)
123 *sizeof(Dict_char), client);
125 hi = DICT_nodir(p)-1;
128 indxp[-mid] = indxp[-mid-1];
133 dict_bf_touch(dict->dbf, ptr);
136 r = 1; /* signal deleted */
137 /* start again (may not be the most efficient way to go)*/
143 /* normal delete: delete if equal */
146 hi = DICT_nodir(p)-1;
149 indxp[-mid] = indxp[-mid-1];
154 dict_bf_touch(dict->dbf, ptr);
164 /* Dict_ptr subptr */
165 /* Dict_char sub char */
166 /* unsigned char length of information */
167 /* char * information */
168 info = (char*)p - indxp[-mid];
169 memcpy(&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
173 memcpy(&subptr, info, sizeof(Dict_ptr));
174 if (*++str == DICT_EOS)
176 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
178 /* entry does exist. Wipe it out */
179 info[sizeof(Dict_ptr)+sizeof(Dict_char)] = 0;
181 dict_bf_touch(dict->dbf, ptr);
184 (*f)(info+sizeof(Dict_ptr)+sizeof(Dict_char),
190 /* must delete all suffixes (subtrees) as well */
191 hi = DICT_nodir(p)-1;
194 indxp[-mid] = indxp[-mid-1];
199 dict_bf_touch(dict->dbf, ptr);
204 /* subptr may be 0 */
205 r = dict_del_string(dict, str, subptr, sub_flag, client, f);
208 dict_bf_readp(dict->dbf, ptr, &p);
210 ((char*) p+DICT_bsize(p)-sizeof(short));
211 info = (char*)p - indxp[-mid];
213 subptr = 0; /* avoid dict_del_subtree (end of function)*/
215 { /* subptr page became empty and is removed */
217 /* see if this entry is a real one or if it just
218 serves as pointer to subptr */
219 if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
221 /* this entry do exist, set subptr to 0 */
222 memcpy(info, &subptr, sizeof(subptr));
226 /* this entry ONLY points to subptr. remove it */
227 hi = DICT_nodir(p)-1;
230 indxp[-mid] = indxp[-mid-1];
235 dict_bf_touch(dict->dbf, ptr);
247 if (DICT_nodir(p) == 0 && ptr != dict->head.root)
249 DICT_backptr(p) = dict->head.freelist;
250 dict->head.freelist = ptr;
251 dict_bf_touch(dict->dbf, ptr);
254 if (subptr && sub_flag)
255 dict_del_subtree(dict, subptr, client, f);
260 int dict_delete(Dict dict, const char *p)
262 return dict_del_string(dict, (const Dict_char*) p, dict->head.root, 0,
266 int dict_delete_subtree(Dict dict, const char *p, void *client,
267 int (*f)(const char *info, void *client))
269 return dict_del_string(dict, (const Dict_char*) p, dict->head.root, 1,
275 * c-file-style: "Stroustrup"
276 * indent-tabs-mode: nil
278 * vim: shiftwidth=4 tabstop=8 expandtab