Fix dict_delete that could delete wrong entry
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 23 Mar 2011 17:45:25 +0000 (18:45 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 23 Mar 2011 17:45:25 +0000 (18:45 +0100)
dict_delete could delete entry X if entries XY (Y suffixes) were
all removed. If prefix entry X was a real entry (not just a subptr
entry) it would be removed too. dict_del_string now checks if
X is a real entry or not before removing.. In case of real entry
subptr is just set to 0.

dict/delete.c

index f3d26cb..b8ac9da 100644 (file)
@@ -207,19 +207,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];
 
                         ((char*) p+DICT_bsize(p)-sizeof(short));
                     info = (char*)p - indxp[-mid];
 
+                    subptr = 0; /* avoid dict_del_subtree (end of function)*/
                     if (r == 2)
                     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;
                     }
                         dict_bf_touch(dict->dbf, ptr);
                         r = 1;
                     }
-                    subptr = 0; /* prevent dict_del_subtree (below) */
                 }
                 break;
             }
                 }
                 break;
             }