+ DICT_size(p) = info- (char*) p;
+ dict_bf_touch (dict->dbf, ptr);
+ if (cmp)
+ return 0;
+ return 1;
+}
+/* return 0 if new */
+/* return 1 if before but change of info */
+/* return 2 if same as before */
+
+#else
+static int dict_ins (Dict dict, const Dict_char *str,
+ Dict_ptr back_ptr, int userlen, void *userinfo)
+{
+ int hi, lo, mid, i, 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);
+
+ assert (p);
+ assert (ptr);
+
+ mid = lo = 0;
+ hi = DICT_nodir(p)-1;
+ indxp = (short*) ((char*) p+DICT_PAGESIZE-sizeof(short));
+ while (lo <= hi)
+ {
+ mid = (lo+hi)/2;
+ if (indxp[-mid] > 0)
+ {
+ info = (char*)p + indxp[-mid];
+ cmp = dict_strcmp((Dict_char*) info, str);
+ if (!cmp)
+ {
+ info += (dict_strlen(info)+1)*sizeof(Dict_char);
+ /* consider change of userinfo length... */
+ if (*info == userlen)
+ {
+ if (memcmp (info+1, userinfo, userlen))
+ {
+ dict_bf_touch (dict->dbf, ptr);
+ memcpy (info+1, userinfo, userlen);
+ return 1;
+ }
+ return 2;
+ }
+ else if (*info > userlen)
+ {
+ DICT_type(p) = 1;
+ *info = userlen;
+ dict_bf_touch (dict->dbf, ptr);
+ memcpy (info+1, userinfo, userlen);
+ return 1;
+ }
+ else
+ DICT_type(p) = 1;
+ break;
+ }
+ }
+ else
+ {
+ Dict_char dc;
+ Dict_ptr subptr;
+
+ info = (char*)p - indxp[-mid];
+ memcpy (&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
+ cmp = dc- *str;
+ if (!cmp)
+ {
+ memcpy (&subptr, info, sizeof(Dict_ptr));
+ if (*++str == DICT_EOS)
+ {
+ int xlen;
+
+ xlen = info[sizeof(Dict_ptr)+sizeof(Dict_char)];
+ if (xlen == userlen)
+ {
+ if (memcmp (info+sizeof(Dict_ptr)+sizeof(Dict_char)+1,
+ userinfo, userlen))
+ {
+ dict_bf_touch (dict->dbf, ptr);
+ memcpy (info+sizeof(Dict_ptr)+sizeof(Dict_char)+1,
+ userinfo, userlen);
+ return 1;
+ }
+ return 2;
+ }
+ else if (xlen > userlen)
+ {
+ DICT_type(p) = 1;
+ info[sizeof(Dict_ptr)+sizeof(Dict_char)] = userlen;
+ memcpy (info+sizeof(Dict_ptr)+sizeof(Dict_char)+1,
+ userinfo, userlen);
+ dict_bf_touch (dict->dbf, ptr);
+ return 1;
+ }
+ if (DICT_size(p)+sizeof(Dict_char)+sizeof(Dict_ptr)+
+ userlen >=
+ DICT_PAGESIZE - (1+DICT_nodir(p))*sizeof(short))
+ {
+ assert (0);
+ clean_page (dict, ptr, p);
+ dict_ins (dict, str-1, ptr, userlen, userinfo);
+ }
+ else
+ {
+ info = (char*)p + DICT_size(p);
+ memcpy (info, &subptr, sizeof(subptr));
+ memcpy (info+sizeof(Dict_ptr), &dc, sizeof(Dict_char));
+ info[sizeof(Dict_char)+sizeof(Dict_ptr)] = userlen;
+ memcpy (info+sizeof(Dict_char)+sizeof(Dict_ptr)+1,
+ userinfo, userlen);
+ indxp[-mid] = -DICT_size(p);
+ DICT_size(p) += sizeof(Dict_char)+sizeof(Dict_ptr)
+ +1+userlen;
+ DICT_type(p) = 1;
+ dict_bf_touch (dict->dbf, ptr);
+ }
+ if (xlen)
+ return 1;
+ return 0;
+ }
+ else
+ {
+ if (subptr == 0)
+ {
+ subptr = new_page (dict, ptr, NULL);
+ memcpy (info, &subptr, sizeof(subptr));
+ dict_bf_touch (dict->dbf, ptr);
+ }
+ return dict_ins (dict, str, subptr, userlen, userinfo);
+ }
+ }
+ }
+ if (cmp < 0)
+ lo = mid+1;
+ else
+ hi = mid-1;
+ }
+ indxp = indxp-mid;
+ if (lo>hi && cmp < 0)
+ --indxp;
+ slen = (dict_strlen(str)+1)*sizeof(Dict_char);
+ if (DICT_size(p)+slen+userlen >=
+ DICT_PAGESIZE - (1+DICT_nodir(p))*sizeof(short)) /* overflow? */
+ {
+ if (DICT_type(p) == 1)
+ {
+ clean_page (dict, ptr, p);
+ dict_bf_touch (dict->dbf, ptr);
+ return dict_ins (dict, str, ptr, userlen, userinfo);
+ }
+ i = 0;
+ do
+ {
+ assert (i <= 1);
+ if (split_page (dict, ptr, p))
+ {
+ log (LOG_FATAL, "Unable to split page %d\n", ptr);
+ abort ();
+ }
+ if (DICT_size(p)+slen+userlen <
+ DICT_PAGESIZE - (1+DICT_nodir(p))*sizeof(short))
+ break;
+ i++;
+ clean_page (dict, ptr, p);
+ } while (DICT_size(p)+slen+userlen > DICT_PAGESIZE -
+ (1+DICT_nodir(p))*sizeof(short));
+ return dict_ins (dict, str, ptr, userlen, userinfo);
+ }
+ if (cmp)
+ {
+ short *indxp1;
+ (DICT_nodir(p))++;
+ indxp1 = (short*)((char*) p + DICT_PAGESIZE
+ - DICT_nodir(p)*sizeof(short));
+ for (; indxp1 != indxp; indxp1++)
+ indxp1[0] = indxp1[1];
+#if CHECK
+ indxp1 = (short*) ((char*) p+DICT_PAGESIZE-sizeof(short));
+ for (i = DICT_nodir (p); --i >= 0; --indxp1)
+ {
+ if (*indxp1 < 0)
+ {
+ info = (char*)p - *indxp1;
+ assert (info[sizeof(Dict_ptr)] > ' ');
+ }
+ }