X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=dict%2Fdelete.c;h=55743fa43a01967a080d521b6133ccab20f801e4;hp=388e95de98079d7bd344e1a5a3604d1781eed493;hb=c3ff843e467932c6027a8b3b2ebda7b44612447e;hpb=475d4ac8314b3d6a24b974246af581662e0b6c02 diff --git a/dict/delete.c b/dict/delete.c index 388e95d..55743fa 100644 --- a/dict/delete.c +++ b/dict/delete.c @@ -1,5 +1,5 @@ /* This file is part of the Zebra server. - Copyright (C) 1994-2009 Index Data + Copyright (C) Index Data Zebra is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -17,6 +17,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#if HAVE_CONFIG_H +#include +#endif #include #include #include @@ -25,16 +28,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "dict-p.h" static void dict_del_subtree(Dict dict, Dict_ptr ptr, - void *client, + void *client, int (*f)(const char *, void *)) { void *p = 0; short *indxp; int i, hi; - + if (!ptr) return; - + dict_bf_readp(dict->dbf, ptr, &p); indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short)); hi = DICT_nodir(p)-1; @@ -53,14 +56,14 @@ static void dict_del_subtree(Dict dict, Dict_ptr ptr, else { Dict_ptr subptr; - + /* Dict_ptr subptr */ /* Dict_char sub char */ /* unsigned char length of information */ /* char * information */ char *info = (char*)p - indxp[-i]; memcpy(&subptr, info, sizeof(Dict_ptr)); - + if (info[sizeof(Dict_ptr)+sizeof(Dict_char)]) { if (f) @@ -69,7 +72,7 @@ static void dict_del_subtree(Dict dict, Dict_ptr ptr, if (subptr) { dict_del_subtree(dict, subptr, client, f); - + /* page may be gone. reread it .. */ dict_bf_readp(dict->dbf, ptr, &p); indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short)); @@ -82,7 +85,7 @@ static void dict_del_subtree(Dict dict, Dict_ptr ptr, } static int dict_del_string(Dict dict, const Dict_char *str, Dict_ptr ptr, - int sub_flag, void *client, + int sub_flag, void *client, int (*f)(const char *, void *)) { int mid, lo, hi; @@ -98,7 +101,7 @@ static int dict_del_string(Dict dict, const Dict_char *str, Dict_ptr ptr, dict_bf_readp(dict->dbf, ptr, &p); mid = lo = 0; hi = DICT_nodir(p)-1; - indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short)); + indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short)); while (lo <= hi) { mid = (lo+hi)/2; @@ -132,7 +135,7 @@ static int dict_del_string(Dict dict, const Dict_char *str, Dict_ptr ptr, mid = lo = 0; r = 1; /* signal deleted */ /* start again (may not be the most efficient way to go)*/ - continue; + continue; } } else @@ -207,19 +210,31 @@ static int dict_del_string(Dict dict, const Dict_char *str, Dict_ptr ptr, ((char*) p+DICT_bsize(p)-sizeof(short)); info = (char*)p - indxp[-mid]; + subptr = 0; /* avoid dict_del_subtree (end of function)*/ if (r == 2) - { /* subptr page is empty and already removed */ - hi = DICT_nodir(p)-1; - while (mid < hi) + { /* subptr page became empty and is removed */ + + /* see if this entry is a real one or if it just + serves as pointer to subptr */ + if (info[sizeof(Dict_ptr)+sizeof(Dict_char)]) { - indxp[-mid] = indxp[-mid-1]; - mid++; + /* this entry do exist, set subptr to 0 */ + memcpy(info, &subptr, sizeof(subptr)); + } + else + { + /* this entry ONLY points to subptr. remove it */ + hi = DICT_nodir(p)-1; + while (mid < hi) + { + indxp[-mid] = indxp[-mid-1]; + mid++; + } + (DICT_nodir(p))--; } - (DICT_nodir(p))--; dict_bf_touch(dict->dbf, ptr); r = 1; } - subptr = 0; /* prevent dict_del_subtree (below) */ } break; }