X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=index%2Fextract.c;h=9207ab76518cfe7c1f09d8cee96b5f249d3771c6;hb=83762ea76e5af65ccb4407c6b38053bc6491a875;hp=9b7f76bd42c8d1dd16edb56273082a6fd07ca097;hpb=ca19a15163ee74ee0c6765bfef4fd9794627e26a;p=idzebra-moved-to-github.git diff --git a/index/extract.c b/index/extract.c index 9b7f76b..9207ab7 100644 --- a/index/extract.c +++ b/index/extract.c @@ -4,7 +4,55 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: extract.c,v $ - * Revision 1.10 1995-09-28 09:19:41 adam + * Revision 1.26 1995-11-20 11:56:24 adam + * Work on new traversal. + * + * Revision 1.25 1995/11/16 15:34:54 adam + * Uses new record management system in both indexer and server. + * + * Revision 1.24 1995/11/15 19:13:08 adam + * Work on record management. + * + * Revision 1.23 1995/10/27 14:00:10 adam + * Implemented detection of database availability. + * + * Revision 1.22 1995/10/17 18:02:07 adam + * New feature: databases. Implemented as prefix to words in dictionary. + * + * Revision 1.21 1995/10/10 12:24:38 adam + * Temporary sort files are compressed. + * + * Revision 1.20 1995/10/06 13:52:05 adam + * Bug fixes. Handler may abort further scanning. + * + * Revision 1.19 1995/10/04 12:55:16 adam + * Bug fix in ranked search. Use=Any keys inserted. + * + * Revision 1.18 1995/10/04 09:37:08 quinn + * Fixed bug. + * + * Revision 1.17 1995/10/03 14:28:57 adam + * Buffered read in extract works. + * + * Revision 1.16 1995/10/03 14:28:45 adam + * Work on more effecient read handler in extract. + * + * Revision 1.15 1995/10/02 15:42:53 adam + * Extract uses file descriptors instead of FILE pointers. + * + * Revision 1.14 1995/10/02 15:29:13 adam + * More logging in file_extract. + * + * Revision 1.13 1995/09/29 14:01:39 adam + * Bug fixes. + * + * Revision 1.12 1995/09/28 14:22:56 adam + * Sort uses smaller temporary files. + * + * Revision 1.11 1995/09/28 12:10:31 adam + * Bug fixes. Field prefix used in queries. + * + * Revision 1.10 1995/09/28 09:19:41 adam * xfree/xmalloc used everywhere. * Extract/retrieve method seems to work for text records. * @@ -49,34 +97,51 @@ #include #include "index.h" +#if RECORD_BASE +#include "recindex.h" +#endif + static Dict file_idx; -static SYSNO sysno_next; -static int key_fd = -1; + + +#if RECORD_BASE +static Records records = NULL; +#else static int sys_idx_fd = -1; -static char *key_buf; -static int key_offset, key_buf_size; +static SYSNO sysno_next; +#endif + static int key_cmd; static int key_sysno; +static char *key_databaseName; +static char **key_buf; +static size_t ptr_top; +static size_t ptr_i; +static size_t kused; +static int key_file_no; -void key_open (const char *fname) +void key_open (int mem) { +#if !RECORD_BASE void *file_key; - if (key_fd != -1) - return; - if ((key_fd = open (fname, O_RDWR|O_CREAT, 0666)) == -1) - { - logf (LOG_FATAL|LOG_ERRNO, "open %s", fname); - exit (1); - } - logf (LOG_DEBUG, "key_open of %s", fname); - key_buf_size = 49100; - key_buf = xmalloc (key_buf_size); - key_offset = 0; +#endif + if (mem < 50000) + mem = 50000; + key_buf = xmalloc (mem); + ptr_top = mem/sizeof(char*); + ptr_i = 0; + kused = 0; + key_file_no = 0; + if (!(file_idx = dict_open (FNAME_FILE_DICT, 40, 1))) { logf (LOG_FATAL, "dict_open fail of %s", "fileidx"); exit (1); } +#if RECORD_BASE + assert (!records); + records = rec_open (1); +#else file_key = dict_lookup (file_idx, "."); if (file_key) memcpy (&sysno_next, (char*)file_key+1, sizeof(sysno_next)); @@ -87,104 +152,262 @@ void key_open (const char *fname) logf (LOG_FATAL|LOG_ERRNO, "open %s", FNAME_SYS_IDX); exit (1); } +#endif } -int key_close (void) +struct encode_info { + int sysno; + int seqno; + char buf[512]; +}; + +void encode_key_init (struct encode_info *i) { - if (key_fd == -1) + i->sysno = 0; + i->seqno = 0; +} + +char *encode_key_int (int d, char *bp) +{ + if (d <= 63) + *bp++ = d; + else if (d <= 16383) { - logf (LOG_DEBUG, "key_close - but no file"); - return 0; + *bp++ = 64 + (d>>8); + *bp++ = d & 255; } - close (key_fd); - close (sys_idx_fd); - dict_insert (file_idx, ".", sizeof(sysno_next), &sysno_next); - dict_close (file_idx); - key_fd = -1; - xfree (key_buf); - return 1; + else if (d <= 4194303) + { + *bp++ = 128 + (d>>16); + *bp++ = (d>>8) & 255; + *bp++ = d & 255; + } + else + { + *bp++ = 192 + (d>>24); + *bp++ = (d>>16) & 255; + *bp++ = (d>>8) & 255; + *bp++ = d & 255; + } + return bp; } -void wordFlush (int sysno) +void encode_key_write (char *k, struct encode_info *i, FILE *outf) { - size_t i = 0; - int w; + struct it_key key; + char *bp = i->buf; - if (key_fd == -1) - return; - while (i < key_offset) + while ((*bp++ = *k++)) + ; + memcpy (&key, k+1, sizeof(struct it_key)); + bp = encode_key_int ( (key.sysno - i->sysno) * 2 + *k, bp); + if (i->sysno != key.sysno) { - w = write (key_fd, key_buf + i, key_offset - i); - if (w == -1) + i->sysno = key.sysno; + i->seqno = 0; + } + bp = encode_key_int (key.seqno - i->seqno, bp); + i->seqno = key.seqno; + if (fwrite (i->buf, bp - i->buf, 1, outf) != 1) + { + logf (LOG_FATAL|LOG_ERRNO, "fwrite"); + exit (1); + } +} + +void key_flush (void) +{ + FILE *outf; + char out_fname[200]; + char *prevcp, *cp; + struct encode_info encode_info; + + if (ptr_i <= 0) + return; + + key_file_no++; + logf (LOG_LOG, "sorting section %d", key_file_no); + qsort (key_buf + ptr_top-ptr_i, ptr_i, sizeof(char*), key_qsort_compare); + sprintf (out_fname, TEMP_FNAME, key_file_no); + + if (!(outf = fopen (out_fname, "w"))) + { + logf (LOG_FATAL|LOG_ERRNO, "fopen (4) %s", out_fname); + exit (1); + } + logf (LOG_LOG, "writing section %d", key_file_no); + prevcp = cp = key_buf[ptr_top-ptr_i]; + + encode_key_init (&encode_info); + encode_key_write (cp, &encode_info, outf); + while (--ptr_i > 0) + { + cp = key_buf[ptr_top-ptr_i]; + if (strcmp (cp, prevcp)) { - logf (LOG_FATAL|LOG_ERRNO, "Write key fail"); - exit (1); + encode_key_init (&encode_info); + encode_key_write (cp, &encode_info, outf); + prevcp = cp; } - i += w; + else + encode_key_write (cp + strlen(cp), &encode_info, outf); } - key_offset = 0; + if (fclose (outf)) + { + logf (LOG_FATAL|LOG_ERRNO, "fclose %s", out_fname); + exit (1); + } + logf (LOG_LOG, "finished section %d", key_file_no); + ptr_i = 0; + kused = 0; +} + +int key_close (void) +{ + key_flush (); + xfree (key_buf); +#if RECORD_BASE + rec_close (&records); +#else + close (sys_idx_fd); + dict_insert (file_idx, ".", sizeof(sysno_next), &sysno_next); +#endif + dict_close (file_idx); + return key_file_no; } static void wordInit (RecWord *p) { p->attrSet = 1; - p->attrUse = 1; + p->attrUse = 1016; p->which = Word_String; } static void wordAdd (const RecWord *p) { struct it_key key; - char x; size_t i; - char wordPrefix[8]; - if (key_offset + 1000 > key_buf_size) - { - char *new_key_buf; - - key_buf_size *= 2; - new_key_buf = xmalloc (2*key_buf_size); - memcpy (new_key_buf, key_buf, key_offset); - xfree (key_buf); - key_buf = new_key_buf; - } - sprintf (wordPrefix, "%c%04d", p->attrSet + '0', p->attrUse); - strcpy (key_buf + key_offset, wordPrefix); - key_offset += strlen (wordPrefix); + if (kused + 1024 > (ptr_top-ptr_i)*sizeof(char*)) + key_flush (); + ++ptr_i; + key_buf[ptr_top-ptr_i] = (char*)key_buf + kused; + kused += index_word_prefix ((char*)key_buf + kused, + p->attrSet, p->attrUse, + key_databaseName); switch (p->which) { case Word_String: for (i = 0; p->u.string[i]; i++) - key_buf[key_offset++] = index_char_cvt (p->u.string[i]); - key_buf[key_offset++] = '\0'; + ((char*)key_buf) [kused++] = index_char_cvt (p->u.string[i]); + ((char*)key_buf) [kused++] = '\0'; break; default: return ; } - x = (key_cmd == 'a') ? 1 : 0; - memcpy (key_buf + key_offset, &x, 1); - key_offset++; - + ((char*) key_buf)[kused++] = ((key_cmd == 'a') ? 1 : 0); key.sysno = key_sysno; - key.seqno = p->seqno; - memcpy (key_buf + key_offset, &key, sizeof(key)); - key_offset += sizeof(key); + key.seqno = p->seqno; + memcpy ((char*)key_buf + kused, &key, sizeof(key)); + kused += sizeof(key); +} + +static void wordAddAny (const RecWord *p) +{ + if (p->attrSet != 1 || p->attrUse != 1016) + { + RecWord w; + + memcpy (&w, p, sizeof(w)); + w.attrSet = 1; + w.attrUse = 1016; + wordAdd (&w); + } + wordAdd (p); +} + + +#define FILE_READ_BUF 1 +#if FILE_READ_BUF +static char *file_buf; +static int file_offset; +static int file_bufsize; + +static void file_read_start (int fd) +{ + file_offset = 0; + file_buf = xmalloc (4096); + file_bufsize = read (fd, file_buf, 4096); +} + +static void file_read_stop (int fd) +{ + xfree (file_buf); } -void file_extract (int cmd, const char *fname, const char *kname) +static int file_read (int fd, char *buf, size_t count) { - int i; + int l = file_bufsize - file_offset; + + if (count > l) + { + int r; + if (l > 0) + memcpy (buf, file_buf + file_offset, l); + count = count-l; + if (count > file_bufsize) + { + if ((r = read (fd, buf + l, count)) == -1) + { + logf (LOG_FATAL|LOG_ERRNO, "read"); + exit (1); + } + file_bufsize = 0; + file_offset = 0; + return r; + } + file_bufsize = r = read (fd, file_buf, 4096); + if (r == -1) + { + logf (LOG_FATAL|LOG_ERRNO, "read"); + exit (1); + } + else if (r <= count) + { + file_offset = r; + memcpy (buf + l, file_buf, r); + return l + r; + } + else + { + file_offset = count; + memcpy (buf + l, file_buf, count - l); + return count; + } + } + memcpy (buf, file_buf + file_offset, count); + file_offset += count; + return count; +} +#else +static int file_read (int fd, char *buf, size_t count) +{ + return read (fd, buf, count); +} +#endif +SYSNO file_extract (int cmd, const char *fname, const char *kname, + char *databaseName) +{ + int i, r; char ext[128]; SYSNO sysno; char ext_res[128]; const char *file_type; void *file_info; - FILE *inf; struct recExtractCtrl extractCtrl; RecType rt; - logf (LOG_DEBUG, "%c %s k=%s", cmd, fname, kname); + key_databaseName = databaseName; for (i = strlen(fname); --i >= 0; ) if (fname[i] == '/') { @@ -198,35 +421,53 @@ void file_extract (int cmd, const char *fname, const char *kname) } sprintf (ext_res, "fileExtension.%s", ext); if (!(file_type = res_get (common_resource, ext_res))) - return; + return 0; if (!(rt = recType_byName (file_type))) - return; + return 0; + logf (LOG_DEBUG, "%c %s k=%s", cmd, fname, kname); file_info = dict_lookup (file_idx, kname); if (!file_info) { +#if RECORD_BASE + Record rec = rec_new (records); + + sysno = rec->sysno; + dict_insert (file_idx, kname, sizeof(sysno), &sysno); + rec->info[0] = rec_strdup (file_type); + rec->info[1] = rec_strdup (kname); + rec_put (records, rec); + rec_rm (rec); +#else sysno = sysno_next++; dict_insert (file_idx, kname, sizeof(sysno), &sysno); lseek (sys_idx_fd, sysno * SYS_IDX_ENTRY_LEN, SEEK_SET); write (sys_idx_fd, file_type, strlen (file_type)+1); write (sys_idx_fd, kname, strlen(kname)+1); +#endif } else memcpy (&sysno, (char*) file_info+1, sizeof(sysno)); - if (!(inf = fopen (fname, "r"))) + if ((extractCtrl.fd = open (fname, O_RDONLY)) == -1) { logf (LOG_WARN|LOG_ERRNO, "open %s", fname); - return; + return 0; } - extractCtrl.inf = inf; extractCtrl.subType = ""; extractCtrl.init = wordInit; - extractCtrl.add = wordAdd; + extractCtrl.add = wordAddAny; +#if FILE_READ_BUF + file_read_start (extractCtrl.fd); +#endif + extractCtrl.readf = file_read; key_sysno = sysno; key_cmd = cmd; - (*rt->extract)(&extractCtrl); - fclose (inf); - wordFlush (sysno); + r = (*rt->extract)(&extractCtrl); +#if FILE_READ_BUF + file_read_stop (extractCtrl.fd); +#endif + close (extractCtrl.fd); + if (r) + logf (LOG_WARN, "Couldn't extract file %s, code %d", fname, r); + return sysno; } - -