C++ compilation.
[idzebra-moved-to-github.git] / dict / insert.c
index ce41de7..1057d67 100644 (file)
@@ -1,10 +1,22 @@
 /*
- * Copyright (C) 1994-1996, Index Data I/S 
+ * Copyright (C) 1994-1999, Index Data
  * All rights reserved.
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: insert.c,v $
- * Revision 1.17  1996-05-14 15:49:09  adam
+ * Revision 1.21  1999-05-26 07:49:12  adam
+ * C++ compilation.
+ *
+ * Revision 1.20  1999/05/15 14:36:37  adam
+ * Updated dictionary. Implemented "compression" of dictionary.
+ *
+ * Revision 1.19  1999/02/02 14:50:22  adam
+ * Updated WIN32 code specific sections. Changed header.
+ *
+ * Revision 1.18  1998/03/05 08:17:24  adam
+ * Added a few comments - no code changed.
+ *
+ * Revision 1.17  1996/05/14 15:49:09  adam
  * Bug fix: In function split_page. In rare cases variable best_indxp was
  * referenced.
  *
@@ -82,26 +94,24 @@ static void clean_page (Dict dict, Dict_ptr ptr, void *p, Dict_char *out,
 static Dict_ptr new_page (Dict dict, Dict_ptr back_ptr, void **pp)
 {
     void *p;
-    Dict_ptr ptr = dict->head.free_list;
-    if (dict->head.free_list == dict->head.last)
+    Dict_ptr ptr = dict->head.last;
+    if (!dict->head.freelist)
     {
-        dict->head.free_list++;
-        dict->head.last = dict->head.free_list;
-        dict_bf_newp (dict->dbf, ptr, &p);
+        dict_bf_newp (dict->dbf, dict->head.last, &p, dict->head.page_size);
+       (dict->head.last)++;
     }
     else
     {
-        dict_bf_readp (dict->dbf, dict->head.free_list, &p);
-        dict->head.free_list = DICT_nextptr(p);
-        if (dict->head.free_list == 0)
-            dict->head.free_list = dict->head.last;
+       ptr = dict->head.freelist;
+        dict_bf_readp (dict->dbf, ptr, &p);
+        dict->head.freelist = DICT_backptr(p);
     }
     assert (p);
     DICT_type(p) = 0;
     DICT_backptr(p) = back_ptr;
-    DICT_nextptr(p) = 0;
     DICT_nodir(p) = 0;
     DICT_size(p) = DICT_infoffset;
+    DICT_bsize(p) = dict->head.page_size;
     if (pp)
         *pp = p;
     return ptr;
@@ -119,7 +129,7 @@ static int split_page (Dict dict, Dict_ptr ptr, void *p)
     int best_no = -1, no_current = 1;
 
     /* determine splitting char... */
-    indxp = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short));
+    indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
     for (i = DICT_nodir (p); --i >= 0; --indxp)
     {
         if (*indxp > 0) /* tail string here! */
@@ -162,23 +172,22 @@ static int split_page (Dict dict, Dict_ptr ptr, void *p)
         char *info, *info1;
         int slen;
         Dict_char dc;
-        
 
         info = (char*) p + ((short*) p)[j];
         /* entry start */
         memcpy (&dc, info, sizeof(dc));
         assert (dc == best_char);
-        slen = dict_strlen((Dict_char*) info);
+        slen = 1+dict_strlen((Dict_char*) info);
 
-        assert (slen > 0);
-        if (slen == 1)
+        assert (slen > 1);
+        if (slen == 2)
         {
             assert (!info_here);
-            info_here = info+(slen+1)*sizeof(Dict_char);
+            info_here = info+slen*sizeof(Dict_char);
         }
         else
         {
-            info1 = info+(1+slen)*sizeof(Dict_char);  /* info start */
+            info1 = info+slen*sizeof(Dict_char);  /* info start */
             dict_ins (dict, (Dict_char*) (info+sizeof(Dict_char)),
                       subptr, *info1, info1+1);
             dict_bf_readp (dict->dbf, ptr, &p);
@@ -192,13 +201,14 @@ static int split_page (Dict dict, Dict_ptr ptr, void *p)
 static void clean_page (Dict dict, Dict_ptr ptr, void *p, Dict_char *out,
                         Dict_ptr subptr, char *userinfo)             
 {
-    char *np = xmalloc (dict->head.page_size);
+    char *np = (char *) xmalloc (dict->head.page_size);
     int i, slen, no = 0;
     short *indxp1, *indxp2;
     char *info1, *info2;
 
-    indxp1 = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short));
-    indxp2 = (short*) ((char*) np+DICT_pagesize(dict));
+    DICT_bsize(np) = dict->head.page_size;
+    indxp1 = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
+    indxp2 = (short*) ((char*) np+DICT_bsize(np));
     info2 = (char*) np + DICT_infoffset;
     for (i = DICT_nodir (p); --i >= 0; --indxp1)
     {
@@ -260,7 +270,7 @@ static void clean_page (Dict dict, Dict_ptr ptr, void *p, Dict_char *out,
             info2 - ((char*)np+DICT_infoffset));
     memcpy ((char*)p + ((char*)indxp2 - (char*)np),
             indxp2,
-            ((char*) np+DICT_pagesize(dict)) - (char*)indxp2);
+            ((char*) np+DICT_bsize(p)) - (char*)indxp2);
 #else
     memcpy ((char*)p+DICT_infoffset, (char*)np+DICT_infoffset,
             DICT_pagesize(dict)-DICT_infoffset);
@@ -279,25 +289,21 @@ static void clean_page (Dict dict, Dict_ptr ptr, void *p, Dict_char *out,
 /* return 2 if same as before */
 
 static int dict_ins (Dict dict, const Dict_char *str,
-                     Dict_ptr back_ptr, int userlen, void *userinfo)
+                     Dict_ptr ptr, int userlen, void *userinfo)
 {
     int hi, lo, mid, slen, cmp = 1;
-    Dict_ptr ptr = back_ptr;
     short *indxp;
     char *info;
     void *p;
 
-    if (ptr == 0)
-        ptr = new_page (dict, back_ptr, &p);
-    else
-        dict_bf_readp (dict->dbf, ptr, &p);
+    dict_bf_readp (dict->dbf, ptr, &p);
         
     assert (p);
     assert (ptr);
 
     mid = lo = 0;
     hi = DICT_nodir(p)-1;
-    indxp = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short));
+    indxp = (short*) ((char*) p+DICT_bsize(p)-sizeof(short));
     while (lo <= hi)
     {
         mid = (lo+hi)/2;
@@ -314,16 +320,19 @@ static int dict_ins (Dict dict, const Dict_char *str,
                 /* consider change of userinfo length... */
                 if (*info == userlen)
                 {
+                   /* change of userinfo ? */
                     if (memcmp (info+1, userinfo, userlen))
                     {
                         dict_bf_touch (dict->dbf, ptr);
                         memcpy (info+1, userinfo, userlen);
                         return 1;
                     }
+                   /* same userinfo */
                     return 2;
                 }
                 else if (*info > userlen)
                 {
+                   /* room for new userinfo */
                     DICT_type(p) = 1;
                     *info = userlen;
                     dict_bf_touch (dict->dbf, ptr);
@@ -350,9 +359,9 @@ static int dict_ins (Dict dict, const Dict_char *str,
                 memcpy (&subptr, info, sizeof(Dict_ptr));
                 if (*++str == DICT_EOS)
                 {
-                    int xlen;
-                    
-                    xlen = info[sizeof(Dict_ptr)+sizeof(Dict_char)];
+                   /* finish of string. Store userinfo here... */
+
+                    int xlen = info[sizeof(Dict_ptr)+sizeof(Dict_char)];
                     if (xlen == userlen)
                     {
                         if (memcmp (info+sizeof(Dict_ptr)+sizeof(Dict_char)+1,
@@ -374,10 +383,12 @@ static int dict_ins (Dict dict, const Dict_char *str,
                         dict_bf_touch (dict->dbf, ptr);
                         return 1;
                     }
+                   /* xlen < userlen, expanding needed ... */
                     if (DICT_size(p)+sizeof(Dict_char)+sizeof(Dict_ptr)+
                         userlen >=
-                        DICT_pagesize(dict) - (1+DICT_nodir(p))*sizeof(short))
+                        DICT_bsize(p) - (1+DICT_nodir(p))*sizeof(short))
                     {
+                       /* not enough room - split needed ... */
                         if (DICT_type(p) == 1)
                         {
                             clean_page (dict, ptr, p, NULL, 0, NULL);
@@ -392,7 +403,7 @@ static int dict_ins (Dict dict, const Dict_char *str,
                         return dict_ins (dict, str-1, ptr, userlen, userinfo);
                     }
                     else
-                    {
+                    {   /* enough room - no split needed ... */
                         info = (char*)p + DICT_size(p);
                         memcpy (info, &subptr, sizeof(subptr));
                         memcpy (info+sizeof(Dict_ptr), &dc, sizeof(Dict_char));
@@ -431,7 +442,7 @@ static int dict_ins (Dict dict, const Dict_char *str,
         --indxp;
     slen = (dict_strlen(str)+1)*sizeof(Dict_char);
     if (DICT_size(p)+slen+userlen >=
-        DICT_pagesize(dict) - (1+DICT_nodir(p))*sizeof(short)) /* overflow? */
+        (int)(DICT_bsize(p) - (1+DICT_nodir(p))*sizeof(short)))/* overflow? */
     {
         if (DICT_type(p))
         {
@@ -445,7 +456,7 @@ static int dict_ins (Dict dict, const Dict_char *str,
     {
         short *indxp1;
         (DICT_nodir(p))++;
-        indxp1 = (short*)((char*) p + DICT_pagesize(dict)
+        indxp1 = (short*)((char*) p + DICT_bsize(p)
                           - DICT_nodir(p)*sizeof(short));
         for (; indxp1 != indxp; indxp1++)
             indxp1[0] = indxp1[1];
@@ -480,10 +491,15 @@ static int dict_ins (Dict dict, const Dict_char *str,
 
 int dict_insert (Dict dict, const char *str, int userlen, void *userinfo)
 {
-    assert (dict->head.last > 0);
-    if (dict->head.last == 1)
-        return dict_ins (dict, (const Dict_char *) str, 0, userlen, userinfo);
-    else
-        return dict_ins (dict, (const Dict_char *) str, 1, userlen, userinfo);
+    if (!dict->head.root)
+    {
+       void *p;
+       if (dict->rw)
+           dict->head.root = new_page (dict, 0, &p);
+       if (!dict->head.root)
+           return 0;
+    }
+    return dict_ins (dict, (const Dict_char *) str, dict->head.root,
+                    userlen, userinfo);
 }