For buffer_extract_sysno, match criteria is only used if SYSNO pointer
[idzebra-moved-to-github.git] / index / extract.c
index 2da4282..f92ca7f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: extract.c,v 1.190 2005-08-19 09:45:24 adam Exp $
+/* $Id: extract.c,v 1.200 2005-12-09 10:45:04 adam Exp $
    Copyright (C) 1995-2005
    Index Data ApS
 
@@ -99,14 +99,10 @@ static void extract_init (struct recExtractCtrl *p, RecWord *w)
 }
 
 static void searchRecordKey(ZebraHandle zh,
-                           const struct recKeys *reckeys,
+                           zebra_rec_keys_t reckeys,
                            int attrSetS, int attrUseS,
                            const char **ws, int ws_length)
 {
-    void *decode_handle = iscz1_start();
-    int off = 0;
-    int startSeq = -1;
-    int seqno = 0;
     int i;
     int ch;
 
@@ -118,34 +114,31 @@ static void searchRecordKey(ZebraHandle zh,
     if (ch < 0)
        return ;
 
-    while (off < reckeys->buf_used)
+    if (zebra_rec_keys_rewind(reckeys))
     {
-        const char *src = reckeys->buf + off;
-        struct it_key key;
-       char *dst = (char*) &key;
-
-       iscz1_decode(decode_handle, &dst, &src);
-       assert(key.len <= 4 && key.len > 2);
-
-       seqno = (int) key.mem[key.len-1];
-
-       if (key.mem[0] == ch)
-        {
-            int woff;
-
-            if (startSeq == -1)
-                startSeq = seqno;
-            woff = seqno - startSeq;
-            if (woff >= 0 && woff < ws_length)
-                ws[woff] = src;
-        }
+       int startSeq = -1;
+       const char *str;
+       size_t slen;
+       struct it_key key;
+       zint seqno;
+       while (zebra_rec_keys_read(reckeys, &str, &slen, &key))
+       {
+           assert(key.len <= 4 && key.len > 2);
 
-        while (*src++)
-           ;
-        off = src - reckeys->buf;
+           seqno = key.mem[key.len-1];
+           
+           if (key.mem[0] == ch)
+           {
+               int woff;
+               
+               if (startSeq == -1)
+                   startSeq = seqno;
+               woff = seqno - startSeq;
+               if (woff >= 0 && woff < ws_length)
+                   ws[woff] = str;
+           }
+       }
     }
-    iscz1_stop(decode_handle);
-    assert (off == reckeys->buf_used);
 }
 
 struct file_read_info {
@@ -214,7 +207,7 @@ static void file_end (void *handle, off_t offset)
 }
 
 static char *fileMatchStr (ZebraHandle zh,
-                           struct recKeys *reckeys,
+                          zebra_rec_keys_t reckeys,
                            const char *fname, const char *spec)
 {
     static char dstBuf[2048];      /* static here ??? */
@@ -369,12 +362,6 @@ struct recordLogInfo {
     struct recordGroup *rGroup;
 };
 
-void create_rec_keys_codec(struct recKeys *keys)
-{
-    keys->buf_used = 0;
-    iscz1_reset(keys->codec_handle);
-}
-
 static void init_extractCtrl(ZebraHandle zh, struct recExtractCtrl *ctrl)
 {
     int i;
@@ -416,9 +403,10 @@ static int file_extract_record(ZebraHandle zh,
     if (fi->fd != -1)
     {
         /* we are going to read from a file, so prepare the extraction */
-       create_rec_keys_codec(&zh->reg->keys);
+       zebra_rec_keys_reset(zh->reg->keys);
+
 #if NATTR
-       create_rec_keys_codec(&zh->reg->sortKeys);
+       zebra_rec_keys_reset(zh->reg->sortKeys);
 #else
        zh->reg->sortKeys.buf_used = 0;
 #endif
@@ -492,8 +480,7 @@ static int file_extract_record(ZebraHandle zh,
 
         if (matchStr == 0 && zh->m_record_id && *zh->m_record_id)
         {
-        
-            matchStr = fileMatchStr (zh, &zh->reg->keys, fname, 
+            matchStr = fileMatchStr (zh, zh->reg->keys, fname, 
                                     zh->m_record_id);
            if (!matchStr)
            {
@@ -511,7 +498,7 @@ static int file_extract_record(ZebraHandle zh,
            }
        }
     }
-    if (! *sysno && zh->reg->keys.buf_used == 0)
+    if (! *sysno && zebra_rec_keys_empty(zh->reg->keys)        )
     {
          /* the extraction process returned no information - the record
             is probably empty - unless flagShowRecords is in use */
@@ -548,18 +535,22 @@ static int file_extract_record(ZebraHandle zh,
         {
             dict_insert (zh->reg->matchDict, matchStr, sizeof(*sysno), sysno);
         }
+#if NATTR
+       extract_flushSortKeys (zh, *sysno, 1, zh->reg->sortKeys);
+#else
        extract_flushSortKeys (zh, *sysno, 1, &zh->reg->sortKeys);
-        extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys,
+#endif
+        extract_flushRecordKeys (zh, *sysno, 1, zh->reg->keys,
                                 recordAttr->staticrank);
-
         zh->records_inserted++;
     }
     else
     {
         /* record already exists */
-        struct recKeys delkeys;
+       zebra_rec_keys_t delkeys = zebra_rec_keys_open();
+
 #if NATTR
-       struct recKeys sortKeys;
+       zebra_rec_keys_t sortKeys = zebra_rec_keys_open();
 #else
         struct sortKeys sortKeys;
 #endif
@@ -569,42 +560,39 @@ static int file_extract_record(ZebraHandle zh,
        
        recordAttr = rec_init_attr (zh->reg->zei, rec);
 
-       if (!force_update && recordAttr->runNumber ==
-            zebraExplain_runNumberIncrement (zh->reg->zei, 0))
-       {
-            yaz_log (YLOG_LOG, "run number = " ZINT_FORMAT,
-                           recordAttr->runNumber);
-           yaz_log (YLOG_LOG, "skipped %s %s " PRINTF_OFF_T,
-                     zh->m_record_type, fname, recordOffset);
-           extract_flushSortKeys (zh, *sysno, -1, &zh->reg->sortKeys);
-           rec_rm (&rec);
-           logRecord (zh);
-           return 1;
-       }
-       /* flush old keys for sort&search etc. */
-        delkeys.buf_used = rec->size[recInfo_delKeys];
-       delkeys.buf = rec->info[recInfo_delKeys];
+       zebra_rec_keys_set_buf(delkeys,
+                              rec->info[recInfo_delKeys],
+                              rec->size[recInfo_delKeys],
+                              0);
 
+#if NATTR
+       zebra_rec_keys_set_buf(sortKeys,
+                              rec->info[recInfo_sortKeys],
+                              rec->size[recInfo_sortKeys],
+                              0);
+       extract_flushSortKeys (zh, *sysno, 0, sortKeys);
+#else
         sortKeys.buf_used = rec->size[recInfo_sortKeys];
         sortKeys.buf = rec->info[recInfo_sortKeys];
-
        extract_flushSortKeys (zh, *sysno, 0, &sortKeys);
-        extract_flushRecordKeys (zh, *sysno, 0, &delkeys,
+#endif
+
+        extract_flushRecordKeys (zh, *sysno, 0, delkeys,
                                 recordAttr->staticrank); /* old values */  
         if (deleteFlag)
         {
             /* record going to be deleted */
-            if (!delkeys.buf_used)
+            if (zebra_rec_keys_empty(delkeys))
             {
                 yaz_log (YLOG_LOG, "delete %s %s " PRINTF_OFF_T,
-                      zh->m_record_type, fname, recordOffset);
-                yaz_log (YLOG_WARN, "cannot delete file above, storeKeys false");
+                        zh->m_record_type, fname, recordOffset);
+                yaz_log (YLOG_WARN, "cannot delete file above, storeKeys false (1)");
             }
             else
             {
                 if (zh->records_processed < zh->m_file_verbose_limit)
                     yaz_log (YLOG_LOG, "delete %s %s " PRINTF_OFF_T,
-                         zh->m_record_type, fname, recordOffset);
+                            zh->m_record_type, fname, recordOffset);
                 zh->records_deleted++;
                 if (matchStr)
                     dict_delete (zh->reg->matchDict, matchStr);
@@ -616,26 +604,24 @@ static int file_extract_record(ZebraHandle zh,
         }
         else
         {
-            /* record going to be updated */
-            if (!delkeys.buf_used)
-            {
+           /* flush new keys for sort&search etc */
+            if (zh->records_processed < zh->m_file_verbose_limit)
                 yaz_log (YLOG_LOG, "update %s %s " PRINTF_OFF_T,
                       zh->m_record_type, fname, recordOffset);
-                yaz_log (YLOG_WARN, "cannot update file above, storeKeys false");
-            }
-            else
-            {
-               /* flush new keys for sort&search etc */
-                if (zh->records_processed < zh->m_file_verbose_limit)
-                    yaz_log (YLOG_LOG, "update %s %s " PRINTF_OFF_T,
-                        zh->m_record_type, fname, recordOffset);
-               recordAttr->staticrank = extractCtrl.staticrank;
-                extract_flushSortKeys (zh, *sysno, 1, &zh->reg->sortKeys);
-                extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys,
+           recordAttr->staticrank = extractCtrl.staticrank;
+#if NATTR
+            extract_flushSortKeys (zh, *sysno, 1, zh->reg->sortKeys);
+#else
+            extract_flushSortKeys (zh, *sysno, 1, &zh->reg->sortKeys);
+#endif
+            extract_flushRecordKeys (zh, *sysno, 1, zh->reg->keys,
                                         recordAttr->staticrank);
-                zh->records_updated++;
-            }
+            zh->records_updated++;
         }
+       zebra_rec_keys_close(delkeys);
+#if NATTR
+       zebra_rec_keys_close(sortKeys);
+#endif
     }
     /* update file type */
     xfree (rec->info[recInfo_fileType]);
@@ -649,12 +635,11 @@ static int file_extract_record(ZebraHandle zh,
 
     /* update delete keys */
     xfree (rec->info[recInfo_delKeys]);
-    if (zh->reg->keys.buf_used > 0 && zh->m_store_keys == 1)
+    if (!zebra_rec_keys_empty(zh->reg->keys) && zh->m_store_keys == 1)
     {
-        rec->size[recInfo_delKeys] = zh->reg->keys.buf_used;
-        rec->info[recInfo_delKeys] = zh->reg->keys.buf;
-        zh->reg->keys.buf = NULL;
-        zh->reg->keys.buf_max = 0;
+       zebra_rec_keys_get_buf(zh->reg->keys,
+                              &rec->info[recInfo_delKeys],
+                              &rec->size[recInfo_delKeys]);
     }
     else
     {
@@ -665,10 +650,16 @@ static int file_extract_record(ZebraHandle zh,
     /* update sort keys */
     xfree (rec->info[recInfo_sortKeys]);
 
+#if NATTR
+    zebra_rec_keys_get_buf(zh->reg->sortKeys,
+                          &rec->info[recInfo_sortKeys],
+                          &rec->size[recInfo_sortKeys]);
+#else
     rec->size[recInfo_sortKeys] = zh->reg->sortKeys.buf_used;
     rec->info[recInfo_sortKeys] = zh->reg->sortKeys.buf;
     zh->reg->sortKeys.buf = NULL;
     zh->reg->sortKeys.buf_max = 0;
+#endif
 
     /* save file size of original record */
     zebraExplain_recordBytesIncrement (zh->reg->zei,
@@ -843,17 +834,18 @@ int fileExtract (ZebraHandle zh, SYSNO *sysno, const char *fname,
   If not, and a record is provided, then sysno is got from there
   
  */
-ZEBRA_RES buffer_extract_record (ZebraHandle zh, 
-                                const char *buf, size_t buf_size,
-                                int delete_flag,
-                                int test_mode, 
-                                const char *recordType,
-                                SYSNO *sysno,
-                                const char *match_criteria,
-                                const char *fname,
-                                int force_update,
-                                int allow_update)
+ZEBRA_RES buffer_extract_record(ZebraHandle zh, 
+                               const char *buf, size_t buf_size,
+                               int delete_flag,
+                               int test_mode, 
+                               const char *recordType,
+                               SYSNO *sysno,
+                               const char *match_criteria,
+                               const char *fname,
+                               int force_update,
+                               int allow_update)
 {
+    SYSNO sysno0 = 0;
     RecordAttr *recordAttr;
     struct recExtractCtrl extractCtrl;
     int r;
@@ -884,9 +876,10 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
     extractCtrl.first_record = 1;
     extractCtrl.fh = &fc;
 
-    create_rec_keys_codec(&zh->reg->keys);
+    zebra_rec_keys_reset(zh->reg->keys);
+
 #if NATTR
-    create_rec_keys_codec(&zh->reg->sortKeys);
+    zebra_rec_keys_reset(zh->reg->sortKeys);
 #else
     zh->reg->sortKeys.buf_used = 0;
 #endif
@@ -950,19 +943,19 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
        yaz_log (YLOG_WARN, "extract error: no such filter");
        return ZEBRA_FAIL;
     }
-    /* match criteria */
-    matchStr = NULL;
 
     if (extractCtrl.match_criteria[0])
        match_criteria = extractCtrl.match_criteria;
 
-    if (! *sysno) {
-        char *rinfo;
+    if (!sysno) {
+
+       sysno = &sysno0;
+
         if (match_criteria && *match_criteria) {
             matchStr = match_criteria;
         } else {
             if (zh->m_record_id && *zh->m_record_id) {
-                matchStr = fileMatchStr (zh, &zh->reg->keys, pr_fname, 
+                matchStr = fileMatchStr (zh, zh->reg->keys, pr_fname, 
                                          zh->m_record_id);
                if (!matchStr)
                 {
@@ -972,7 +965,7 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
             }
         }
         if (matchStr) {
-            rinfo = dict_lookup (zh->reg->matchDict, matchStr);
+           char *rinfo = dict_lookup (zh->reg->matchDict, matchStr);
             if (rinfo)
            {
                assert(*rinfo == sizeof(*sysno));
@@ -980,7 +973,7 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
            }
         }
     }
-    if (zh->reg->keys.buf_used == 0)
+    if (zebra_rec_keys_empty(zh->reg->keys))
     {
        /* the extraction process returned no information - the record
           is probably empty - unless flagShowRecords is in use */
@@ -993,8 +986,7 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
         /* new record */
         if (delete_flag)
         {
-           if (show_progress)
-               yaz_log (YLOG_LOG, "delete %s %s %ld", recordType,
+           yaz_log (YLOG_LOG, "delete %s %s %ld", recordType,
                         pr_fname, (long) recordOffset);
             yaz_log (YLOG_WARN, "cannot delete record above (seems new)");
             return ZEBRA_FAIL;
@@ -1014,26 +1006,32 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
             dict_insert (zh->reg->matchDict, matchStr,
                          sizeof(*sysno), sysno);
         }
+#if NATTR
+       extract_flushSortKeys (zh, *sysno, 1, zh->reg->sortKeys);
+#else
        extract_flushSortKeys (zh, *sysno, 1, &zh->reg->sortKeys);
-        extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys,
-                                recordAttr->staticrank);
-
+#endif
+       
+#if 0
+       print_rec_keys(zh, zh->reg->keys);
+#endif
+        extract_flushRecordKeys (zh, *sysno, 1, zh->reg->keys,
+                        recordAttr->staticrank);
         zh->records_inserted++;
     } 
     else
     {
         /* record already exists */
-        struct recKeys delkeys;
+       zebra_rec_keys_t delkeys = zebra_rec_keys_open();
 #if NATTR
-       struct recKeys sortKeys;
+       zebra_rec_keys_t sortKeys = zebra_rec_keys_open();
 #else
         struct sortKeys sortKeys;
 #endif
 
        if (!allow_update)
        {
-           if (show_progress)
-               yaz_log (YLOG_LOG, "skipped %s %s %ld", 
+           yaz_log (YLOG_LOG, "skipped %s %s %ld", 
                         recordType, pr_fname, (long) recordOffset);
            logRecord(zh);
            return ZEBRA_FAIL;
@@ -1043,42 +1041,37 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
         assert (rec);
        
        recordAttr = rec_init_attr (zh->reg->zei, rec);
-       
-       if (!force_update) {
-           if (recordAttr->runNumber ==
-               zebraExplain_runNumberIncrement (zh->reg->zei, 0))
-           {
-               if (show_progress)
-                   yaz_log (YLOG_LOG, "skipped %s %s %ld", recordType,
-                            pr_fname, (long) recordOffset);
-               extract_flushSortKeys (zh, *sysno, -1, &zh->reg->sortKeys);
-               rec_rm (&rec);
-               logRecord(zh);
-               return ZEBRA_FAIL;
-           }
-       }
-
-        delkeys.buf_used = rec->size[recInfo_delKeys];
-       delkeys.buf = rec->info[recInfo_delKeys];
 
+       zebra_rec_keys_set_buf(delkeys,
+                              rec->info[recInfo_delKeys],
+                              rec->size[recInfo_delKeys],
+                              0);
+#if NATTR
+       zebra_rec_keys_set_buf(sortKeys,
+                              rec->info[recInfo_sortKeys],
+                              rec->size[recInfo_sortKeys],
+                              0);
+#else
         sortKeys.buf_used = rec->size[recInfo_sortKeys];
         sortKeys.buf = rec->info[recInfo_sortKeys];
+#endif
 
+#if NATTR
+       extract_flushSortKeys (zh, *sysno, 0, sortKeys);
+#else
        extract_flushSortKeys (zh, *sysno, 0, &sortKeys);
-        extract_flushRecordKeys (zh, *sysno, 0, &delkeys,
+#endif
+        extract_flushRecordKeys (zh, *sysno, 0, delkeys,
                                 recordAttr->staticrank);
         if (delete_flag)
         {
             /* record going to be deleted */
-            if (!delkeys.buf_used)
+            if (zebra_rec_keys_empty(delkeys))
             {
-               if (show_progress)
-               {
-                   yaz_log (YLOG_LOG, "delete %s %s %ld", recordType,
-                            pr_fname, (long) recordOffset);
-                   yaz_log (YLOG_WARN, "cannot delete file above, "
-                            "storeKeys false");
-               }
+               yaz_log (YLOG_LOG, "delete %s %s %ld", recordType,
+                    pr_fname, (long) recordOffset);
+               yaz_log (YLOG_WARN, "cannot delete file above, "
+                            "storeKeys false (3)");
            }
             else
             {
@@ -1096,28 +1089,23 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
         }
         else
         {
-            /* record going to be updated */
-            if (!delkeys.buf_used)
-            {
-               if (show_progress)
-               {
-                   yaz_log (YLOG_LOG, "update %s %s %ld", recordType,
-                            pr_fname, (long) recordOffset);
-                   yaz_log (YLOG_WARN, "cannot update file above, storeKeys false");
-               }
-           }
-            else
-            {
-               if (show_progress)
+           if (show_progress)
                    yaz_log (YLOG_LOG, "update %s %s %ld", recordType,
                             pr_fname, (long) recordOffset);
-               recordAttr->staticrank = extractCtrl.staticrank;
-                extract_flushSortKeys (zh, *sysno, 1, &zh->reg->sortKeys);
-                extract_flushRecordKeys (zh, *sysno, 1, &zh->reg->keys, 
+           recordAttr->staticrank = extractCtrl.staticrank;
+#if NATTR
+            extract_flushSortKeys (zh, *sysno, 1, zh->reg->sortKeys);
+#else
+            extract_flushSortKeys (zh, *sysno, 1, &zh->reg->sortKeys);
+#endif
+            extract_flushRecordKeys (zh, *sysno, 1, zh->reg->keys, 
                                         recordAttr->staticrank);
-                zh->records_updated++;
-            }
+            zh->records_updated++;
         }
+       zebra_rec_keys_close(delkeys);
+#if NATTR
+       zebra_rec_keys_close(sortKeys);
+#endif
     }
     /* update file type */
     xfree (rec->info[recInfo_fileType]);
@@ -1131,26 +1119,30 @@ ZEBRA_RES buffer_extract_record (ZebraHandle zh,
 
     /* update delete keys */
     xfree (rec->info[recInfo_delKeys]);
-    if (zh->reg->keys.buf_used > 0 && zh->m_store_keys == 1)
+    if (!zebra_rec_keys_empty(zh->reg->keys) && zh->m_store_keys == 1)
     {
-        rec->size[recInfo_delKeys] = zh->reg->keys.buf_used;
-        rec->info[recInfo_delKeys] = zh->reg->keys.buf;
-        zh->reg->keys.buf = NULL;
-        zh->reg->keys.buf_max = 0;
+       zebra_rec_keys_get_buf(zh->reg->keys,
+                              &rec->info[recInfo_delKeys],
+                              &rec->size[recInfo_delKeys]);
     }
     else
     {
         rec->info[recInfo_delKeys] = NULL;
         rec->size[recInfo_delKeys] = 0;
     }
-
     /* update sort keys */
     xfree (rec->info[recInfo_sortKeys]);
 
+#if NATTR
+    zebra_rec_keys_get_buf(zh->reg->sortKeys,
+                          &rec->info[recInfo_sortKeys],
+                          &rec->size[recInfo_sortKeys]);
+#else
     rec->size[recInfo_sortKeys] = zh->reg->sortKeys.buf_used;
     rec->info[recInfo_sortKeys] = zh->reg->sortKeys.buf;
     zh->reg->sortKeys.buf = NULL;
     zh->reg->sortKeys.buf_max = 0;
+#endif
 
     /* save file size of original record */
     zebraExplain_recordBytesIncrement (zh->reg->zei,
@@ -1219,9 +1211,10 @@ int explain_extract (void *handle, Record rec, data1_node *n)
             abort ();
     }
 
-    create_rec_keys_codec(&zh->reg->keys);
+    zebra_rec_keys_reset(zh->reg->keys);
+    
 #if NATTR
-    create_rec_keys_codec(&zh->reg->sortKeys);
+    zebra_rec_keys_reset(zh->reg->sortKeys);
 #else
     zh->reg->sortKeys.buf_used = 0;
 #endif
@@ -1245,47 +1238,64 @@ int explain_extract (void *handle, Record rec, data1_node *n)
 
     if (rec->size[recInfo_delKeys])
     {
-       struct recKeys delkeys;
+       zebra_rec_keys_t delkeys = zebra_rec_keys_open();
+       
 #if NATTR
-       struct recKeys sortkeys;
+       zebra_rec_keys_t sortkeys = zebra_rec_keys_open();
 #else
        struct sortKeys sortkeys;
 #endif
 
-       delkeys.buf_used = rec->size[recInfo_delKeys];
-       delkeys.buf = rec->info[recInfo_delKeys];
+       zebra_rec_keys_set_buf(delkeys, rec->info[recInfo_delKeys],
+                              rec->size[recInfo_delKeys],
+                              0);
+       extract_flushRecordKeys (zh, rec->sysno, 0, delkeys, 0);
+       zebra_rec_keys_close(delkeys);
+#if NATTR
+       zebra_rec_keys_set_buf(sortkeys, rec->info[recInfo_sortKeys],
+                              rec->size[recInfo_sortKeys],
+                              0);
 
+       extract_flushSortKeys (zh, rec->sysno, 0, sortkeys);
+       zebra_rec_keys_close(sortkeys);
+#else
        sortkeys.buf_used = rec->size[recInfo_sortKeys];
        sortkeys.buf = rec->info[recInfo_sortKeys];
-
        extract_flushSortKeys (zh, rec->sysno, 0, &sortkeys);
-       extract_flushRecordKeys (zh, rec->sysno, 0, &delkeys, 0);
+#endif
     }
-    extract_flushRecordKeys (zh, rec->sysno, 1, &zh->reg->keys, 0);
+    extract_flushRecordKeys (zh, rec->sysno, 1, zh->reg->keys, 0);
+#if NATTR
+    extract_flushSortKeys (zh, rec->sysno, 1, zh->reg->sortKeys);
+#else
     extract_flushSortKeys (zh, rec->sysno, 1, &zh->reg->sortKeys);
+#endif
 
     xfree (rec->info[recInfo_delKeys]);
-    rec->size[recInfo_delKeys] = zh->reg->keys.buf_used;
-    rec->info[recInfo_delKeys] = zh->reg->keys.buf;
-    zh->reg->keys.buf = NULL;
-    zh->reg->keys.buf_max = 0;
+    zebra_rec_keys_get_buf(zh->reg->keys,
+                          &rec->info[recInfo_delKeys], 
+                          &rec->size[recInfo_delKeys]);
 
     xfree (rec->info[recInfo_sortKeys]);
+#if NATTR
+    zebra_rec_keys_get_buf(zh->reg->sortKeys,
+                          &rec->info[recInfo_sortKeys],
+                          &rec->size[recInfo_sortKeys]);
+#else
     rec->size[recInfo_sortKeys] = zh->reg->sortKeys.buf_used;
     rec->info[recInfo_sortKeys] = zh->reg->sortKeys.buf;
     zh->reg->sortKeys.buf = NULL;
     zh->reg->sortKeys.buf_max = 0;
+#endif
 
     return 0;
 }
 
 void extract_flushRecordKeys (ZebraHandle zh, SYSNO sysno,
-                              int cmd, struct recKeys *reckeys,
+                              int cmd,
+                             zebra_rec_keys_t reckeys,
                              zint staticrank)
 {
-    void *decode_handle = iscz1_start();
-    int off = 0;
-    int ch = 0;
     ZebraExplainInfo zei = zh->reg->zei;
 
     if (!zh->reg->key_buf)
@@ -1306,59 +1316,63 @@ void extract_flushRecordKeys (ZebraHandle zh, SYSNO sysno,
     }
     zebraExplain_recordCountIncrement (zei, cmd ? 1 : -1);
 
-    while (off < reckeys->buf_used)
+    if (zebra_rec_keys_rewind(reckeys))
     {
-        const char *src = reckeys->buf + off;
-        struct it_key key_in;
-       struct it_key key_out;
-       char *dst = (char*) &key_in;
-       zint *keyp = key_out.mem;
-       size_t key_idx = 0;
-
-       iscz1_decode(decode_handle, &dst, &src);
-       assert(key_in.len == 4);
-
-        if (zh->reg->key_buf_used + 1024 > 
-            (zh->reg->ptr_top -zh->reg->ptr_i)*sizeof(char*))
-            extract_flushWriteKeys (zh,0);
-        ++(zh->reg->ptr_i);
-        assert(zh->reg->ptr_i > 0);
-        (zh->reg->key_buf)[zh->reg->ptr_top - zh->reg->ptr_i] =
-           (char*)zh->reg->key_buf + zh->reg->key_buf_used;
-
-       ch = (int) key_in.mem[0];  /* ordinal for field/use/attribute */
-
-       zh->reg->key_buf_used +=
-           key_SU_encode (ch,((char*)zh->reg->key_buf) +
-                           zh->reg->key_buf_used);
-        while (*src)
-            ((char*)zh->reg->key_buf) [(zh->reg->key_buf_used)++] = *src++;
-        src++;
-        ((char*)(zh->reg->key_buf))[(zh->reg->key_buf_used)++] = '\0';
-        ((char*)(zh->reg->key_buf))[(zh->reg->key_buf_used)++] = cmd;
-
-       if (zh->m_staticrank) /* rank config enabled ? */
+       size_t slen;
+       const char *str;
+       struct it_key key_in;
+       while(zebra_rec_keys_read(reckeys, &str, &slen, &key_in))
        {
-           *keyp++ = staticrank;
-           key_out.len = 4;
-       }
-       else
-           key_out.len = 3;
+           int ch = 0;
+           struct it_key key_out;
+           zint *keyp = key_out.mem;
 
-       if (key_in.mem[1]) /* filter specified record ID */
-           *keyp++ = key_in.mem[1];
-       else
-           *keyp++ = sysno;
-       *keyp++ = key_in.mem[2];  /* section_id */
-       *keyp++ = key_in.mem[3];  /* sequence .. */
+           assert(key_in.len == 4);
+           
+           /* check for buffer overflow */
+           if (zh->reg->key_buf_used + 1024 > 
+               (zh->reg->ptr_top -zh->reg->ptr_i)*sizeof(char*))
+               extract_flushWriteKeys (zh, 0);
+           
+           ++(zh->reg->ptr_i);
+           assert(zh->reg->ptr_i > 0);
+           (zh->reg->key_buf)[zh->reg->ptr_top - zh->reg->ptr_i] =
+               (char*)zh->reg->key_buf + zh->reg->key_buf_used;
+
+           /* encode the ordinal value (field/use/attribute) .. */
+           ch = (int) key_in.mem[0];
+           zh->reg->key_buf_used +=
+               key_SU_encode(ch, (char*)zh->reg->key_buf +
+                             zh->reg->key_buf_used);
+           
+           /* copy the 0-terminated stuff from str to output */
+           memcpy((char*)zh->reg->key_buf + zh->reg->key_buf_used, str, slen);
+           zh->reg->key_buf_used += slen;
+           ((char*)zh->reg->key_buf)[(zh->reg->key_buf_used)++] = '\0';
 
-        memcpy ((char*)zh->reg->key_buf + zh->reg->key_buf_used,
-               &key_out, sizeof(key_out));
-        (zh->reg->key_buf_used) += sizeof(key_out);
-        off = src - reckeys->buf;
+           /* the delete/insert indicator */
+           ((char*)zh->reg->key_buf)[(zh->reg->key_buf_used)++] = cmd;
+
+           if (zh->m_staticrank) /* rank config enabled ? */
+           {
+               *keyp++ = staticrank;
+               key_out.len = 4;
+           }
+           else
+               key_out.len = 3;
+           
+           if (key_in.mem[1]) /* filter specified record ID */
+               *keyp++ = key_in.mem[1];
+           else
+               *keyp++ = sysno;
+           *keyp++ = key_in.mem[2];  /* section_id */
+           *keyp++ = key_in.mem[3];  /* sequence .. */
+           
+           memcpy((char*)zh->reg->key_buf + zh->reg->key_buf_used,
+                  &key_out, sizeof(key_out));
+           (zh->reg->key_buf_used) += sizeof(key_out);
+       }
     }
-    assert (off == reckeys->buf_used);
-    iscz1_stop(decode_handle);
 }
 
 void extract_flushWriteKeys (ZebraHandle zh, int final)
@@ -1495,108 +1509,66 @@ void extract_flushWriteKeys (ZebraHandle zh, int final)
     zh->reg->key_buf_used = 0;
 }
 
-void extract_add_it_key (ZebraHandle zh,
-                        struct recKeys *keys,
-                        int reg_type,
-                        const char *str, int slen, struct it_key *key)
-{
-    char *dst;
-    const char *src = (char*) key;
-    
-    if (keys->buf_used+1024 > keys->buf_max)
-    {
-        char *b = (char *) xmalloc (keys->buf_max += 128000);
-        if (keys->buf_used > 0)
-            memcpy (b, keys->buf, keys->buf_used);
-        xfree (keys->buf);
-        keys->buf = b;
-    }
-    dst = keys->buf + keys->buf_used;
-
-    iscz1_encode(keys->codec_handle, &dst, &src);
-
-#if REG_TYPE_PREFIX
-    *dst++ = reg_type;
-#endif
-    memcpy (dst, str, slen);
-    dst += slen;
-    *dst++ = '\0';
-    keys->buf_used = dst - keys->buf;
-}
-
-ZEBRA_RES zebra_snippets_rec_keys(ZebraHandle zh, struct recKeys *reckeys,
+ZEBRA_RES zebra_snippets_rec_keys(ZebraHandle zh,
+                                 zebra_rec_keys_t reckeys,
                                  zebra_snippets *snippets)
 {
-   void *decode_handle = iscz1_start();
-    int off = 0;
-    int seqno = 0;
     NMEM nmem = nmem_create();
-
-    yaz_log(YLOG_LOG, "zebra_rec_keys_snippets buf=%p sz=%d", reckeys->buf,
-           reckeys->buf_used);
-    assert(reckeys->buf);
-    while (off < reckeys->buf_used)
+    if (zebra_rec_keys_rewind(reckeys)) 
     {
-        const char *src = reckeys->buf + off;
-        struct it_key key;
-       char *dst = (char*) &key;
-       char dst_buf[IT_MAX_WORD];
-       char *dst_term = dst_buf;
-
-       iscz1_decode(decode_handle, &dst, &src);
-       assert(key.len <= 4 && key.len > 2);
-
-       seqno = (int) key.mem[key.len-1];
-
-       zebra_term_untrans_iconv(zh, nmem, src[0], &dst_term, src+1);
-       zebra_snippets_append(snippets, seqno, src[0], key.mem[0], dst_term);
-        while (*src++)
-           ;
-        off = src - reckeys->buf;
-       nmem_reset(nmem);
+       const char *str;
+       size_t slen;
+       struct it_key key;
+       while (zebra_rec_keys_read(reckeys, &str, &slen, &key))
+       {
+           char dst_buf[IT_MAX_WORD];
+           char *dst_term = dst_buf;
+           int ord, seqno;
+           int index_type;
+           assert(key.len <= 4 && key.len > 2);
+           seqno = (int) key.mem[key.len-1];
+           ord = key.mem[0];
+           
+           zebraExplain_lookup_ord(zh->reg->zei, ord, &index_type,
+                                   0/* db */, 0/* set */, 0/* use */);
+           assert(index_type);
+           zebra_term_untrans_iconv(zh, nmem, index_type,
+                                    &dst_term, str);
+           zebra_snippets_append(snippets, seqno, ord, dst_term);
+           nmem_reset(nmem);
+       }
     }
     nmem_destroy(nmem);
-    iscz1_stop(decode_handle);
     return ZEBRA_OK;
 }
 
-void print_rec_keys(ZebraHandle zh, struct recKeys *reckeys)
+void print_rec_keys(ZebraHandle zh, zebra_rec_keys_t reckeys)
 {
-    void *decode_handle = iscz1_start();
-    int off = 0;
-    int seqno = 0;
-    NMEM nmem = nmem_create();
-
-    yaz_log(YLOG_LOG, "print_rec_keys buf=%p sz=%d", reckeys->buf,
-           reckeys->buf_used);
-    assert(reckeys->buf);
-    while (off < reckeys->buf_used)
+    yaz_log(YLOG_LOG, "print_rec_keys");
+    if (zebra_rec_keys_rewind(reckeys))
     {
-        const char *src = reckeys->buf + off;
-        struct it_key key;
-       char *dst = (char*) &key;
-       int attrSet, attrUse;
-       char dst_buf[IT_MAX_WORD];
-       char *dst_term = dst_buf;
-
-       iscz1_decode(decode_handle, &dst, &src);
-       assert(key.len <= 4 && key.len > 2);
-
-       attrSet = (int) key.mem[0] >> 16;
-       attrUse = (int) key.mem[0] & 65535;
-       seqno = (int) key.mem[key.len-1];
-
-       zebra_term_untrans_iconv(zh, nmem, src[0], &dst_term, src+1);
-       
-       yaz_log(YLOG_LOG, "ord=" ZINT_FORMAT " seqno=%d term=%s",
-               key.mem[0], seqno, dst_term); 
-        while (*src++)
-           ;
-        off = src - reckeys->buf;
-       nmem_reset(nmem);
+       const char *str;
+       size_t slen;
+       struct it_key key;
+       while (zebra_rec_keys_read(reckeys, &str, &slen, &key))
+       {
+           char dst_buf[IT_MAX_WORD];
+           int seqno;
+           int index_type;
+           const char *db = 0;
+           assert(key.len <= 4 && key.len > 2);
+
+           zebraExplain_lookup_ord(zh->reg->zei,
+                                   key.mem[0], &index_type, &db, 0, 0);
+           
+           seqno = (int) key.mem[key.len-1];
+           
+           zebra_term_untrans(zh, index_type, dst_buf, str);
+           
+           yaz_log(YLOG_LOG, "ord=" ZINT_FORMAT " seqno=%d term=%s",
+                   key.mem[0], seqno, dst_buf); 
+       }
     }
-    nmem_destroy(nmem);
-    iscz1_stop(decode_handle);
 }
 
 void extract_add_index_string (RecWord *p, const char *str, int length)
@@ -1632,16 +1604,23 @@ void extract_add_index_string (RecWord *p, const char *str, int length)
     key.mem[3] = p->seqno;
 
 #if 0
-    /* just for debugging .. */
-    yaz_log(YLOG_LOG, "add: set=%d use=%d "
-           "record_id=%lld section_id=%lld seqno=%lld",
-           p->attrSet, p->attrUse, p->record_id, p->section_id, p->seqno);
+    if (1)
+    {
+       char strz[80];
+       int i;
+
+       strz[0] = 0;
+       for (i = 0; i<length && i < 20; i++)
+           sprintf(strz+strlen(strz), "%02X", str[i] & 0xff);
+       /* just for debugging .. */
+       yaz_log(YLOG_LOG, "add: set=%d use=%d "
+               "record_id=%lld section_id=%lld seqno=%lld %s",
+               p->attrSet, p->attrUse, p->record_id, p->section_id, p->seqno,
+               strz);
+    }
 #endif
 
-    extract_add_it_key(p->extractCtrl->handle, 
-                      &zh->reg->keys,
-                      p->index_type, str,
-                      length, &key);
+    zebra_rec_keys_write(zh->reg->keys, str, length, &key);
 }
 
 #if NATTR
@@ -1669,10 +1648,7 @@ static void extract_add_sort_string (RecWord *p, const char *str, int length)
     key.mem[2] = p->section_id;
     key.mem[3] = p->seqno;
 
-    extract_add_it_key(p->extractCtrl->handle, 
-                      &zh->reg->sortKeys,
-                      p->index_type, str,
-                      length, &key);
+    zebra_rec_keys_write(zh->reg->sortKeys, str, length, &key);
 }
 #else
 static void extract_add_sort_string (RecWord *p, const char *str, int length)
@@ -1685,9 +1661,9 @@ static void extract_add_sort_string (RecWord *p, const char *str, int length)
     {
         int set, use, slen;
 
-        off += key_SU_decode(&set, sk->buf + off);
-        off += key_SU_decode(&use, sk->buf + off);
-        off += key_SU_decode(&slen, sk->buf + off);
+        off += key_SU_decode(&set, (unsigned char *) sk->buf + off);
+        off += key_SU_decode(&use, (unsigned char *) sk->buf + off);
+        off += key_SU_decode(&slen, (unsigned char *) sk->buf + off);
         off += slen;
         if (p->attrSet == set && p->attrUse == use)
             return;
@@ -1885,6 +1861,7 @@ void extract_schema_add (struct recExtractCtrl *p, Odr_oid *oid)
 }
 
 #if NATTR
+#error not done yet with zebra_rec_keys_t
 void extract_flushSortKeys (ZebraHandle zh, SYSNO sysno,
                             int cmd, struct recKeys *reckeys)
 {
@@ -1931,9 +1908,9 @@ void extract_flushSortKeys (ZebraHandle zh, SYSNO sysno,
     {
         int set, use, slen;
         
-        off += key_SU_decode(&set, sk->buf + off);
-        off += key_SU_decode(&use, sk->buf + off);
-        off += key_SU_decode(&slen, sk->buf + off);
+        off += key_SU_decode(&set, (unsigned char *) sk->buf + off);
+        off += key_SU_decode(&use, (unsigned char *) sk->buf + off);
+        off += key_SU_decode(&slen, (unsigned char *) sk->buf + off);
         
         sortIdx_type(sortIdx, use);
         if (cmd == 1)