root/trunk/wtrig2.c

Revision 389, 48.1 kB (checked in by heitor.barbieri, 3 weeks ago)

essage first commit

Line 
1/* Program WTRIG2: trigrams 1B
2*/
3#include <stdio.h>
4#include <string.h>
5#include <ctype.h>
6#include <math.h>
7#include <time.h>
8
9#define MAXNREC (0xFFFF+12+1)  /* set CISIS Interface to 64K records in memory  */
10
11//#define CIWTF 0 
12
13#include "cisis.h"   /* CISIS Interface header file */
14#include "cirun.h"   /* CISIS Interface runtime declarations */
15//#include "cihsh.h"   /* CISIS Interface hashing & binary table search */
16
17//#if !PC
18#ifndef itoa
19char *itoa(int value, char *xa, int len);
20char *itoa(int value, char *xa, int len)
21{
22  if (len) sprintf(xa,"%d",value);
23}
24#endif
25
26#define TAG1   1
27#define TAG2   2
28#define TAG3   3
29#define TAG4   4
30#define TAG5   5
31#define TAG33 33
32
33#define TAG34 34
34#define TAG35 35
35
36#define MAXPARMWIDTH  (LE2+LE2)
37
38#if !CIWTF
39typedef struct vectel {
40    float weight;
41    LONGX hidx;
42} VECTEL;
43
44typedef struct xlista {
45    float sim;
46    LONGX mfn;
47    LONGX xxx;
48    LONGX hit;
49    void *prev;
50    void *next;
51    void *avail;
52} LISTA;
53#endif //CIWTF
54
55void main(int argc, char *argv[])
56{
57    LISTA *lista; /* list of related */
58    LISTA *listhdr,*listtail,*listavail; /* list of related */
59
60
61    VECTEL *VECTORS;
62    LONGX *VECTOFF;
63    LONGX *VECTCNT;
64    LONGX *VECTCMF;
65
66    LONGX COLLECTION_SIZE;     /* N - #docs in collection */
67
68    float *WEIGHT;      /* WEIGHT[] - readnterms */
69    VECTEL *vector;     /*          -         */
70
71    char  *HITS;        /* HITS[] */
72    LONGX hitbytes;
73    unsigned char hitbitmask[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };
74    unsigned char hitmask;
75    LONGX hitmfn;
76    LONGX hitoffset;
77
78    char *table;
79    LONGX tabentries;
80    //LONGX maxprim;
81    //char *h;
82    int hwidth;
83    int found;
84
85    RECSTRU *recp;  /* mandatory for defines REC,MFR,DIR,FIELDP */
86
87    LONGX irec;
88    LONGX irectv;
89    LONGX outcrec;
90    LONGX outirec;
91
92    LONGX vifrec[MAXNREC];
93    LONGX usedifrecs;
94    LONGX leftifrecs;
95    LONGX newparmloadinverted=0;
96    int maxmfrlisincipar=0;
97
98    LONGX docmfn;
99    DIRSTRU *docdirp;
100    int docxdir;
101    FFI docloop;
102    LONGX dochidx;
103
104    LONGX mfn;
105    DIRSTRU *dirp;
106    int xdir,iocc;
107    char *p,*q;
108    char *fldp;
109    int left;
110    FFI loop,keylen;
111
112    char *buff=NULL;
113
114    LONGX count;
115    int iarg;
116
117    int parmcollapse=0;
118    LONGX currentmfncollapsed=0;
119
120    int parmcollmfntag=0;
121    LONGX collhitmfn;
122
123    int readwidth= -1;
124    LONGX readcategories= -1;
125    LONGX readmaxprim= -1;
126    LONGX readcollection_size= -1;
127    int readmaxtv= -1;
128    LONGX readnterms= -1;
129    int readwritebin= -1;
130    int readwritebinv;
131
132    char collectionsizedb[CIMPL+1] = { '\0' };
133    char collectionoccsdb[CIMPL+1] = { '\0' };
134    char collectiontermvectorsdb[CIMPL+1] = { '\0' };
135    char collectionterminverteddb[CIMPL+1] = { '\0' };
136
137    char documenttermvectorsdb[CIMPL+1] = { '\0' };
138    char outsimilardb[CIMPL+1] = { '\0' };
139
140    char *documentsdb=NULL;
141    char *indocumentsdb=NULL;
142    char *parmdocumentsdb=NULL;
143    char *collectiondb=NULL;
144    int parmloadvectors=0;
145    LONGX parmmaxrelat=10;
146    float parmmaxsim=1.0;
147    float parmminsim=0.7;
148    int parmtrace=0;
149    int parmtrace2=0;
150    LONGX parmtell=0;
151    LONGX parmtell2=0;
152    int parmloadinverted=0;
153
154    int parmmaxtv=0;
155
156    int parmwsoma=1;
157    char xa[20];
158
159    int parmlanguage=0;
160    //
161    int readnlangs=0;
162
163#define PARMLANG    1
164#define MAXPARMLANG 32
165#if PARMLANG
166    char *langshits[MAXPARMLANG];
167    char *langsname[MAXPARMLANG];
168    LONGX langscount[MAXPARMLANG];
169    int nlangs=0;
170    int langidx=(-1);
171    int parmchklang=0;
172#endif /* PARMLANG */
173
174
175
176    if (argc < 3) {
177        printf("%s",cicopyr("Utility WTRIG2"));
178        printf(" \n");
179            printf("wtrig2 documents=<mf1>[,<mf3>] collection=<mf2> \n");
180        printf(" \n");
181        printf(" input document term vectors from <mf1>.v \n");
182        printf(" input collection term vectors from <mf2>.v \n");
183        printf(" output similar collection for each input document to <mf1>.y or <mf3>.y \n");
184        printf(" \n");
185        printf(" options: maxrel=<max #related>                               [%"_LD_"]   \n",parmmaxrelat);
186        printf("          minsim=<min similarity for related docs>            [%3.1f] \n",parmminsim);
187        printf("          maxsim=<max similarity for related docs>            [%3.1f] \n",parmmaxsim);
188        printf("          dmfn=<tag>   collapse doc.v as field <mf1>.v/<tag>  [%s]    \n",(parmcollapse)?itoa(parmcollapse,xa,10):"");
189        printf("          cmfn=<tag>   collapse col.v as field <mf2>.v/<tag>  [%s]    \n",(parmcollmfntag)?itoa(parmcollmfntag,xa,10):"");
190        printf("          dlang=<tag>  restrict col.v as field <mf1>.v/<tag>  [%s]    \n",(parmlanguage)?itoa(parmlanguage,xa,10):"");
191        printf(" \n");
192        printf("          doc.v=<mf>   term vector for each document          [document.v]   \n");
193        printf("          col.v=<mf>   term vector for each collection doc    [collection.v] \n");
194        printf("          col.c=<mf>   collection parms                       [collection.c] \n");
195        printf("          col.n=<mf>   terms in collection                    [collection.n] \n");
196        printf("          col.x=<mf>   posting list for each term             [collection.x] \n");
197        printf(" \n");
198        printf("          out.y=<mf>   similar collection for each document   [document.y] \n");
199        printf(" \n");
200        printf("          loadvectors  load all col.v in memory               [%s] \n",(parmloadvectors)?"loadvectors":"");
201        //printf("          loadindex    load part of col.x in memory           [%s] \n",(parmloadinverted)?"loadinverted":"");
202        printf("          loadindex    load all col.x in memory               [%s]     \n",(parmloadinverted)?"loadinverted":"");
203        printf("          loadindex=n  load n recs of col.x in memory         [] (up to %d)\n",MAXNREC-12);
204        //printf("          w2all        weight also terms outside collection   [%s]    \n",(parmwsoma)?"w2all":"");
205        printf("          -w2all       ignore doc terms outside collection    [%s] \n",(parmwsoma)?"":"-w2all");
206        printf("          [maxtv=<n>]  trace[={1|2|4|8|16|32|64|3..127}]      [%d] \n",parmtrace);
207        printf(" \n");
208            exit(1);
209    }
210
211    /* get parameters */
212    for (iarg=1; iarg < argc; iarg++) {
213        p=argv[iarg];
214        if (parmtrace) printf("+++ %s\n",p);
215        if (strcmp(p,"trace") == 0) {
216            parmtrace2=1;
217            parmtrace=127;
218            continue;
219        }
220        if (strncmp(p,"documents?",10) == 0 || strncmp(p,"documents=",10) == 0) {
221            parmdocumentsdb=p+10;
222            if (!*parmdocumentsdb) fatal(p);
223            continue;
224        }
225        if (strncmp(p,"collection?",11) == 0 || strncmp(p,"collection=",11) == 0) {
226            collectiondb=p+11;
227            if (!*collectiondb) fatal(p);
228            continue;
229        }
230        if (strcmp(p,"loadvectors") == 0) {
231            parmloadvectors=1;
232            continue;
233        }
234        if (strcmp(p,"loadindex") == 0) {
235            parmloadinverted=1;
236            continue;
237        }
238        if (strncmp(p,"loadindex?",10) == 0 || strncmp(p,"loadindex=",10) == 0) {
239            if (sscanf(p+10,"%"_LD_,&newparmloadinverted) != 1) fatal(p);
240            if (newparmloadinverted < 2 || newparmloadinverted >= MAXNREC-12) fatal(p);
241            parmloadinverted=1;
242            continue;
243        }
244        if (strncmp(p,"maxrel?",7) == 0 || strncmp(p,"maxrel=",7) == 0) {
245            if (sscanf(p+7,"%"_LD_,&parmmaxrelat) != 1) fatal(p);
246            if (parmmaxrelat < 1) fatal(p);
247            continue;
248        }
249        if (strncmp(p,"maxsim?",7) == 0 || strncmp(p,"maxsim=",7) == 0) {
250            if (sscanf(p+7,"%f",&parmmaxsim) != 1) fatal(p);
251            if (parmmaxsim < 0.0 || parmmaxsim > 1.0) fatal(p);
252            continue;
253        }
254        if (strncmp(p,"minsim?",7) == 0 || strncmp(p,"minsim=",7) == 0) {
255            if (sscanf(p+7,"%f",&parmminsim) != 1) fatal(p);
256            if (parmminsim < 0.0 || parmminsim > 1.0) fatal(p);
257            continue;
258        }
259        if (strncmp(p,"doc.v?",6) == 0 || strncmp(p,"doc.v=",6) == 0) {
260            q=p+6; if (!*q) fatal(p);
261            strcpy(documenttermvectorsdb,q);
262            continue;
263        }
264        if (strncmp(p,"col.c?",6) == 0 || strncmp(p,"col.c=",6) == 0) {
265            q=p+6; if (!*q) fatal(p);
266            strcpy(collectionsizedb,q);
267            continue;
268        }
269        if (strncmp(p,"col.n?",6) == 0 || strncmp(p,"col.n=",6) == 0) {
270            q=p+6; if (!*q) fatal(p);
271            strcpy(collectionoccsdb,q);
272            continue;
273        }
274        if (strncmp(p,"col.v?",6) == 0 || strncmp(p,"col.v=",6) == 0) {
275            q=p+6; if (!*q) fatal(p);
276            strcpy(collectiontermvectorsdb,q);
277            continue;
278        }
279        if (strncmp(p,"col.x?",6) == 0 || strncmp(p,"col.x=",6) == 0) {
280            q=p+6; if (!*q) fatal(p);
281            strcpy(collectionterminverteddb,q);
282            continue;
283        }
284        if (strncmp(p,"out.y?",6) == 0 || strncmp(p,"out.y=",6) == 0) {
285            q=p+6; if (!*q) fatal(p);
286            strcpy(outsimilardb,q);
287            continue;
288        }
289        if (strncmp(p,"dmfn?",5) == 0 || strncmp(p,"dmfn=",5) == 0) {
290            if (sscanf(p+5,"%d",&parmcollapse) != 1) fatal(p);
291            if (parmcollapse < 0) fatal(p);
292            continue;
293        }
294        if (strncmp(p,"cmfn?",5) == 0 || strncmp(p,"cmfn=",5) == 0) {
295            if (sscanf(p+5,"%d",&parmcollmfntag) != 1) fatal(p);
296            if (parmcollmfntag < 0) fatal(p);
297            continue;
298        }
299        if (strncmp(p,"dlang?",6) == 0 || strncmp(p,"dlang=",6) == 0) {
300            if (sscanf(p+6,"%d",&parmlanguage) != 1) fatal(p);
301            if (parmlanguage < 1) fatal(p);
302            continue;
303        }
304        if (strcmp(p,"w2all") == 0) {
305            parmwsoma=1;
306            continue;
307        }
308        if (strcmp(p,"-w2all") == 0) {
309            parmwsoma=0;
310            continue;
311        }
312        if (strncmp(p,"maxtv?",6) == 0 || strncmp(p,"maxtv=",6) == 0) {
313            if (sscanf(p+6,"%d",&parmmaxtv) != 1) fatal(p);
314            if (parmmaxtv < 1) fatal(p);
315            continue;
316        }
317        if (strncmp(p,"tell?",5) == 0 || strncmp(p,"tell=",5) == 0) {
318            if (sscanf(p+5,"%"_LD_,&parmtell) != 1)
319                fatal(p);
320            parmtell2=parmtell;
321            continue;
322        }
323        if (strncmp(p,"tell2?",6) == 0 || strncmp(p,"tell2=",6) == 0) {
324            if (sscanf(p+6,"%"_LD_,&parmtell2) != 1)
325                fatal(p);
326            continue;
327        }
328        if (strncmp(p,"trace?",6) == 0 || strncmp(p,"trace=",6) == 0) {
329            if (sscanf(p+6,"%d",&parmtrace) != 1)
330                fatal(p);
331            continue;
332        }
333        fatal(p);
334    }
335    /* check mandatory parms */
336    if (!parmdocumentsdb) fatal("wtrig2: missing documents= parameter");
337
338    indocumentsdb=documentsdb=strdup(parmdocumentsdb);
339    if ((p=strchr(indocumentsdb,',')) != NULL) {
340        *p='\0';
341        documentsdb=p+1;
342    }
343
344
345    /* alloc working areas
346    */
347    p=dbxcipar(NULL,"maxmfrl",'='); if (dbxcipok) { sscanf(p,"%"_LD_,&rec_maxmfrl); maxmfrlisincipar=1; }
348    recallok(irec=nrecs,rec_maxmfrl);
349    recallok(irectv=nrecs,rec_maxmfrl);
350    recallok(outcrec=nrecs,sizeof(M0STRU));
351    recallok(outirec=nrecs,rec_maxmfrl);
352
353    buff=loadfile(NULL,'@',"",NULL,rec_maxmfrl*2,'\0');
354
355    if (parmtrace2) printf("+++ maxmfrl=%"_LD_"\n",rec_maxmfrl);
356
357
358    /* setup filesnames
359    */
360
361    if (!*collectionsizedb)         sprintf(collectionsizedb,        "%s.c",collectiondb);
362    if (!*collectionoccsdb)         sprintf(collectionoccsdb,        "%s.n",collectiondb);
363    if (!*collectionterminverteddb) sprintf(collectionterminverteddb,"%s.x",collectiondb);
364    if (!*collectiontermvectorsdb)  sprintf(collectiontermvectorsdb, "%s.v",collectiondb);
365
366    if (!*documenttermvectorsdb)    sprintf(documenttermvectorsdb,   "%s.v",indocumentsdb);
367    if (!*outsimilardb)             sprintf(outsimilardb,            "%s.y",documentsdb);
368
369    /* void file names */
370    if (strcmp(collectionterminverteddb,"void") == 0) {
371        collectionterminverteddb[0]='\0';
372        if (newparmloadinverted || parmloadinverted) fatal("wtrig2/loadindex x col.x=void");
373    }
374
375    /* get collection size, classes, width, etc from file
376    */
377    /* get collection size: N */
378    RECORD(irec,collectionsizedb,1);
379    if (RECrc != RCNORMAL) fatal("wtrig2/COLLECTION_SIZE/RCNORMAL");
380    readcollection_size=atol(recfield(buff,irec,TAG2,1,""));
381    /* get other parms */
382    for (iocc=1; *recfield(buff,irec,TAG1,iocc,""); iocc++) {
383        char *q;
384        q="^nK^v";
385        p=strstr(buff,q); if (p) readcategories=atol(p+strlen(q));
386        q="^nwidth^v";
387        p=strstr(buff,q); if (p) readwidth=atoi(p+strlen(q));
388        q="^nmaxprim^v";
389        p=strstr(buff,q); if (p) readmaxprim=atol(p+strlen(q));
390        q="^nmaxtv^v";
391        p=strstr(buff,q); if (p) readmaxtv=atoi(p+strlen(q));
392        q="^nnterms^v";
393        p=strstr(buff,q); if (p) readnterms=atoi(p+strlen(q));
394        q="^nlanguages^v";
395        p=strstr(buff,q); if (p) readnlangs=atoi(p+strlen(q));
396        q="^nbin^v";
397        p=strstr(buff,q); if (p) readwritebin=atoi(p+strlen(q));
398    }
399    if (parmmaxtv) {
400        if (parmmaxtv > readmaxtv) fatal("wtrig2/invalid maxtv");
401        readmaxtv=parmmaxtv;
402    }
403    if (readwidth > MAXPARMWIDTH) fatal("wtrig2/invalid width");
404
405    /* check collection size x collection maxmfn */
406    //RECORD(irec,collectiondb,0);
407    //COLLECTION_SIZE=MF0nxtmfn-1;
408    //if (readcollection_size < COLLECTION_SIZE) fatal("wtrig2/COLLECTION_SIZE");
409    COLLECTION_SIZE=readcollection_size;
410    if (parmtrace & 0x02) {
411        printf(" 2|    |%"_LD_"\n",COLLECTION_SIZE);
412    }
413    readwritebinv=readwritebin;
414
415    /* allocate bsrch table
416    */
417    table=bsrchalloc(readnterms,readwidth,&tabentries);
418
419    if (readnterms > readcategories) fatal("wtrig2/invalid categories or nterms");
420    if (readnterms > readmaxprim)    fatal("wtrig2/invalid maxprim or nterms");
421
422    hwidth=(readwidth+1);
423
424    if (parmtrace2) printf("+++ readnterms=%"_LD_"\n",readnterms);
425    if (parmtrace2) printf("+++ readwidth=%"_LD_"\n",readwidth);
426    if (parmtrace2) printf("+++ tabentries=%"_LD_"\n",tabentries);
427
428    /* loadinverted */
429
430    recallok(vifrec[0]=nrecs,rec_maxmfrl);
431    RECORD(vifrec[0],collectionterminverteddb,0L);
432    if (newparmloadinverted || parmloadinverted) {
433        //recallok(vifrec[0]=nrecs,rec_maxmfrl);
434        //RECORD(vifrec[0],collectionterminverteddb,0L);
435        if (newparmloadinverted >= MF0nxtmfn-1 || parmloadinverted) {
436            if (parmtrace2) printf("+ loading all %"_LD_" index records in memory\n",MF0nxtmfn-1);
437            mstsetup(collectionterminverteddb,LONGX_MAX,LONGX_MAX);
438            parmloadinverted=0; /* CISIS does all we need! */
439        }
440    }
441    if (parmloadinverted) {
442        LONGX nbytes=rec_maxmfrl;
443        if (readwritebin) {
444            nbytes = LEADER + (1+COLLECTION_SIZE)*sizeof(DIRSTRU) + readwidth + COLLECTION_SIZE*sizeof(LONGX);
445            if (nbytes > rec_maxmfrl) {
446                printf("*** nbytes=%"_LD_" rec_maxmfrl=%"_LD_"\n",nbytes,rec_maxmfrl);
447                if (maxmfrlisincipar) fatal("wtrig2/collection size too big for default maxmfrl");
448                else fatal("wtrig2/collection size too big for maxmfrl= defined in CIPAR");
449            }
450        }
451        //recallok(vifrec[0]=nrecs,rec_maxmfrl);
452        leftifrecs=newparmloadinverted-1;
453        usedifrecs=0;
454    }
455
456    /* load collection terms in the hashing table
457    */
458    count=0;
459    for (mfn=1; ; mfn++) {
460        RECORD(irec,collectionoccsdb,mfn);
461        if (RECrc == RCEOF) break;
462        if (RECrc != RCNORMAL) continue;
463        for (dirp=MFRdir, xdir=0, loop=MFRnvf; loop--; dirp++, xdir++) {
464            if (dirp->tag != TAG3) continue;
465            for (keylen=0, p=fldp=FIELDP(xdir), left=dirp->len; left; ) {
466                    if (*p == '^') break;
467                    keylen++; p++; left--;
468            }
469            bsrchindex(table,tabentries,readwidth,fldp,keylen,&found);
470            if (found) fatal("wtrig2/duplicated collection term");
471            bsrchstore(table,readnterms,&tabentries,readwidth,fldp,keylen);
472        }
473        count++;
474        //if (parmtell) if (count%parmtell == 0) fprintf(stderr,"+ %"_LD_"\n",count);
475    }
476    if (parmtell) /*if (count%parmtell == 0)*/ fprintf(stderr,"+ %"_LD_" terms in collection \n",count);
477
478
479    /* allocate list of related
480    */
481    lista=(LISTA *)loadfile(NULL,'@',"",NULL,parmmaxrelat*sizeof(LISTA),'\0');
482
483    /* allocate area for frequencies and weights
484    */
485    hitbytes=COLLECTION_SIZE/8+1; /* bit string size */
486    HITS=  (char  *)loadfile(NULL,'@',"",NULL,hitbytes,'\0');
487
488    WEIGHT=(float *)loadfile(NULL,'@',"",NULL,readnterms*sizeof(float),'\0');
489
490    if (parmloadvectors) {
491        VECTOFF=  (LONGX *)loadfile(NULL,'@',"",NULL,COLLECTION_SIZE*sizeof(LONGX),'\0');
492        VECTCNT=  (LONGX *)loadfile(NULL,'@',"",NULL,COLLECTION_SIZE*sizeof(LONGX),'\0');
493        VECTORS=(VECTEL *)loadfile(NULL,'@',"",NULL,COLLECTION_SIZE*readmaxtv*sizeof(VECTEL),'\0');
494        if (parmcollmfntag)
495        VECTCMF=  (LONGX *)loadfile(NULL,'@',"",NULL,COLLECTION_SIZE*sizeof(LONGX),'\0');
496    }
497    else vector=(VECTEL *)loadfile(NULL,'@',"",NULL,              1*readmaxtv*sizeof(VECTEL),'\0');
498
499
500    /* load all collection' term vectors
501    */
502    if (parmloadvectors) {
503        VECTEL *v=VECTORS;
504        LONGX off=0;
505        LONGX *vcntp=VECTCNT;
506        LONGX *voffp=VECTOFF;
507        LONGX *vcmfp=VECTCMF;
508
509        memset(VECTCNT,0x00,COLLECTION_SIZE*sizeof(LONGX));
510        memset(VECTOFF,0x00,COLLECTION_SIZE*sizeof(LONGX));
511        if (parmcollmfntag)
512        memset(VECTCMF,0x00,COLLECTION_SIZE*sizeof(LONGX));
513
514if (parmtell2) parmtell2=COLLECTION_SIZE/5;
515        count=0;
516        for (mfn=1; mfn <= COLLECTION_SIZE; mfn++) {
517            LONGX cnt=0;
518            RECORD(irectv,collectiontermvectorsdb,mfn);
519            if (RECrc == RCEOF) {
520                //COLLECTION_SIZE=mfn-1;  /* tentativa de otimizar espaco, etc */ /* nao funciona para lilsptv */
521                break;
522            }
523/*
524            if (readwritebinv) {
525                if (fldupdat(irectv,"Gsplit=4=wtrig")) fatal("wtrig2/loadvectors/Gsplit");
526            }
527*/
528            for (dirp=MFRdir, xdir=0, loop=MFRnvf; loop--; dirp++, xdir++) {
529                if (dirp->tag == parmcollmfntag) {
530                    for (collhitmfn=0, p=FIELDP(xdir), left=dirp->len; left; ) {
531                        if (!isdigit(*p)) break;
532                        collhitmfn=collhitmfn*10+((int)(*p)-(int)'0');
533                        p++; left--;
534                    }
535                    if (collhitmfn < 1) fatal("wtrig2/loadvectors/mfn invalid/1");
536                    //if (collhitmfn > COLLECTION_SIZE) fatal("wtrig2/loadvectors/mfn invalid/2"); /* AOT, 11/05/2004 */
537                }
538                if (dirp->tag != TAG4) continue;
539                left=dirp->len;
540                fldp=FIELDP(xdir);
541                if (readwritebinv) {
542                     float b2aweight;
543                     unsigned short int usi_w;
544                     int b2a;
545                     while (left) {
546                        if (cnt >= readmaxtv) break;
547                        b2a=sizeof(usi_w);
548                        if (left < b2a+1) fatal("wtrig2/loadvectors/b2a/left/bin");
549                        memcpy((void *)&usi_w,fldp,b2a);
550                        fldp+=b2a; left-=b2a;
551                        b2aweight=(float)usi_w/(float)USHRT_MAX;
552                        p=fldp; keylen=strlen(p); b2a=0;
553                        while (left) {
554                          q = fldp; fldp++; left--;
555                          if (*q) b2a++; else break;
556                        }
557                        v->weight=b2aweight;
558                        v->hidx=bsrchindex(table,tabentries,readwidth,p,keylen,&found);
559                        if (!found) fatal("wtrig2/loadvectors/TAG4/not found/bin");
560                        v++; cnt++;
561                    }
562                    break;
563                }
564                if (cnt >= readmaxtv) break;
565                for (keylen=0, p=fldp; left; ) {
566                    if (*p == '^') break;
567                    keylen++; p++; left--;
568                }
569                if (left > 2) if (*p++ == '^') if (*p++ == 'w') {  /* ^w */
570                    v->weight=atof(p);
571                }
572                v->hidx=bsrchindex(table,tabentries,readwidth,fldp,keylen,&found);
573                if (!found) fatal("wtrig2/loadvectors/TAG4/not found");
574                v++; cnt++;
575            }
576            *vcntp=cnt; *voffp=off; off+=cnt;
577            vcntp++; voffp++;
578            if (parmcollmfntag) { *vcmfp=collhitmfn; vcmfp++; }
579            count++;
580            //if (parmtell) if (count%parmtell == 0) fprintf(stderr,"++ %"_LD_"\n",count);
581if (parmtell2) if (count%parmtell2 == 0) fprintf(stderr,"++ %"_LD_"/5 \n",(count-1)/parmtell2+1);
582
583        }
584        if (parmtell) /*if (count%parmtell == 0)*/ fprintf(stderr,"++ %"_LD_" term vectors in collection \n",count);
585    }
586
587    /* init output
588    */
589    if (*outsimilardb) {
590        recisis0(outsimilardb);
591        record(outcrec,outsimilardb,0L);
592    }
593
594
595    /* read all language bit strigs
596    */
597#if PARMLANG
598    if (parmlanguage) {
599        if (readnlangs >= MAXPARMLANG) fatal("wtrig2/terminverted/lang/MAXPARMLANG");
600        for (langidx=0; langidx < readnlangs; langidx++) {
601            int xdir;
602            /* read */
603            RECORD(irec,collectionterminverteddb,readnterms+langidx+1);
604            if (RECrc != RCNORMAL) fatal("wtrig2/terminverted/lang/RCNORMAL");
605            /* allocate */
606            langshits[nlangs]=(char  *)loadfile(NULL,'@',"",NULL,hitbytes,'\0');
607            /* store bit string */
608            xdir=fieldx(irec,TAG35,1); if (xdir < 0) fatal("wtrig2/terminverted/lang/TAG35");
609            memcpy(langshits[nlangs],FIELDP(xdir),hitbytes);
610            /* store name */
611            xdir=fieldx(irec,TAG34,1); if (xdir < 0) fatal("wtrig2/terminverted/lang/TAG34");
612            for (p=FIELDP(xdir), left=DIRlen(xdir); left--; ) {
613                if (*p == '^') break;
614                *p=isisuctab[*p]; p++;
615            }
616            *p='\0'; /* ok */
617            langsname[nlangs]=strdup(FIELDP(xdir));
618            langscount[nlangs++]=0;
619        }
620        if (nlangs != readnlangs) fatal("wtrig2/terminverted/lang/nlangs");
621    }
622#endif /* PARMLANG */
623
624
625    /* main loop: process each document against all docs in collection
626    */
627    count=0;
628    for (docmfn=1; ; docmfn++) {
629
630        /* init similarity computation for document only components */
631        float Wsomaq=0; /* init sum of squares for document terms */
632            float somaprod,somaq,simil; /* computation variables */
633
634        /* init document most similar hit */
635        float collapsesim1=0.0;
636        LONGX collapsemfn1=0;
637        LONGX collapsehit1=0;
638
639        LONGX cnt=0;
640
641        /* read term vector */
642        RECORD(irec,documenttermvectorsdb,docmfn);
643        if (RECrc == RCEOF) break;
644        if (RECrc != RCNORMAL) continue;
645
646        if (readwritebinv) {
647            if (fldupdat(irec,"Gsplit=4=wtrig")) fatal("wtrig2/documenttermvectorsdb/Gsplit");
648        }
649
650        /* init list of relevant terms */
651        if (!parmcollapse || !currentmfncollapsed) {
652            LISTA *l;
653            memset(lista,0x00,parmmaxrelat*sizeof(LISTA));
654            for (l=lista, listavail=lista+1, loop=0; (LONGX)loop<(parmmaxrelat-1); loop++, l++, listavail++)
655                l->avail=listavail;
656            listhdr=listtail=listavail=lista;
657        }
658        /* init lastmfncollapse */
659        if (parmcollapse) if (!currentmfncollapsed) {
660            RECSTRU *recp;
661            /* get output mfn, from tag parmcollapse of <mf1>.v */
662            currentmfncollapsed=atol(recfield(buff,irec,parmcollapse,1,""));
663            if (currentmfncollapsed < 1) fatal("wtrig2/documenttermvectorsdb/mfn");
664            /* init output collapsed results record */
665            RECORD(outirec,outsimilardb,currentmfncollapsed); MFRstatus=ACTIVE;
666        }
667
668        /* init term WEIGHTs for the document */
669        memset(WEIGHT,0x00,readnterms*sizeof(float));
670
671        /* init HIT list = docs in collection having 1+ of document terms */
672        memset(HITS,0x00,hitbytes);
673
674#if PARMLANG
675        if (parmlanguage) {
676            int xlang;
677            langidx=(-1);
678            recfield(buff,irec,parmlanguage,1,"");
679            if (parmchklang) if (!*buff) {
680                printf("*** docmfn=%"_LD_" tag=%d\n",docmfn,parmlanguage);
681                fatal("wtrig2/lang/missing");
682            }
683            for (p=buff; *p; ) { *p=isisuctab[*p]; p++; }
684            for (xlang=0; xlang < nlangs; xlang++) {
685                if (strcmp(buff,langsname[xlang]) == 0) { langidx=xlang; break; }
686            }
687            if (parmchklang) if (langidx < 0) if (*buff) {
688                printf("*** docmfn=%"_LD_" tag=%d data=%s\n",docmfn,parmlanguage,buff);
689                for (xlang=0; xlang < nlangs; xlang++) printf("*** idx=%d/%d name=%s\n",xlang,nlangs,langsname[xlang]);
690                fatal("wtrig2/lang/invalid");
691            }
692        }
693#endif /* PARMLANG */
694
695        /* loop term vector fields
696        */
697        for (docdirp=MFRdir, docxdir=0, docloop=MFRnvf; docloop--; docdirp++, docxdir++) {
698            RECSTRU *keeprecp=recp;
699            float weight=0;
700            DIRSTRU *dirp2;
701            int xdir2;
702            FFI keylen2;
703            char *fldp2;
704            char fldarea[BUFSIZ];
705
706            if (docdirp->tag != TAG4) continue;
707
708            if (cnt++ >= readmaxtv) break; /* AOT, 09/05/2004 */
709
710            for (keylen=0, p=fldp=FIELDP(docxdir), left=docdirp->len; left; ) {
711                if (*p == '^') break;
712                keylen++; p++; left--;
713            }
714            if (left > 2) if (*p++ == '^') if (*p++ == 'w') {  /* ^w */
715                *(p+7)='\0';       /* AOT, July 4th, 2004 */  /* ^w0.254383E75^w0.222385 */
716                weight=atof(p);
717            }
718
719            /* convert term key to index: dochidx */
720            dochidx=bsrchindex(table,tabentries,readwidth,fldp,keylen,&found);
721
722            /* keep fldp */
723            memcpy(fldarea,fldp,keylen);
724
725            if (found) {
726                /* similarity computation */
727                Wsomaq += weight * weight;  /* sum of squares for document terms */
728            }
729            else { /* if (lognotfound) ... */
730                if (parmwsoma) {
731                    /* similarity computation */
732                    Wsomaq += weight * weight;  /* sum of squares for document terms */
733                }
734                continue;
735            }
736
737            /* store weight */
738            WEIGHT[dochidx]=weight;
739
740            /* read term's postings from invertedmf and OR them (mfns) into HIT
741            */
742            if (*collectionterminverteddb) {
743                LONGX loop;
744                LONGX irecif;
745                int found=0;
746                if (parmloadinverted) {
747                    for (loop=0; loop < usedifrecs; loop++) {
748                        recp=vrecp[vifrec[loop]];
749                        if (MFRmfn == dochidx+1) { /*irecif=vifrec[loop];*/ found=1; break; }
750                    }
751                    if (!found) {
752                        if (leftifrecs) {
753                            /* load into next */
754                            LONGX ridx;
755                            //for (ridx=maxnrec; ridx--; ) if (!vrecp[ridx]) break;
756                            //if (ridx < 0) fatal("wtrig2/collectionterminverteddb/load/maxnrec");
757                            for (ridx=maxnrec; ridx--; ) if (!vrecp[ridx]) break;
758                            if (ridx < 0) fatal("wtrig2/collectionterminverteddb/load/maxnrec");
759                            irecif=vifrec[1+usedifrecs]=ridx; usedifrecs++; leftifrecs--;
760                        }
761                        else {
762                            /* page out the entry with min mfrl */
763                            LONGX minmfrl=MFRL_MAX;
764                            LONGX x=1;
765                            for (loop=1; loop < usedifrecs; loop++) {
766                                recp=vrecp[vifrec[loop]];
767                                if ((LONGX)MFRmfrl < minmfrl) x=loop;
768                            }
769                            irecif=vifrec[x];
770                        }
771                        RECORD(vifrec[0],collectionterminverteddb,dochidx+1);
772                        if (vrecp[irecif]) if (VMFRmfrl(irecif) < MFRmfrl) {
773                            FREE(vrecp[irecif]); vrecp[irecif]=NULL; nrecs--;
774                        }
775                        if (!vrecp[irecif]) {
776                            recallok(irecif,MFRmfrl); /* RECHSIZE+nbytes is allocated */
777                        }
778                        memcpy(vrecp[irecif],vrecp[vifrec[0]],RECHSIZE+MFRmfrl);
779                        recp=vrecp[irecif]; /* current */
780                    } /* end if !found */
781                } /* end if parmloadinverted */
782                else { /* load into 0 */
783                    irecif=vifrec[0];
784                    RECORD(irecif,collectionterminverteddb,dochidx+1);
785                }
786            } /* end if collectionterminverteddb */
787            //if (RECrc != RCNORMAL) fatal("wtrig2/collectionterminverteddb/deleted");
788            if (*collectionterminverteddb) if (RECrc == RCNORMAL) {
789                LONGX nmfns=0;
790                for (dirp2=MFRdir, xdir2=0, loop=MFRnvf; loop--; dirp2++, xdir2++) {
791                    if (dirp2->tag != TAG33) continue;
792                    for (keylen2=0, p=fldp2=FIELDP(xdir2), left=dirp2->len; left; ) {
793                        if (*p == '^') {
794                            if (left < 2 ) fatal("wtrig2/collectionterminverteddb/nhits/left");
795                            if (*++p != 'n') fatal("wtrig2/collectionterminverteddb/nhits/left");
796                            left-=2;
797                            while (left) {
798                                if (!isdigit(*++p)) break;
799                                nmfns=nmfns*10+((int)(*p)-(int)'0');
800                                left--;
801                            }
802                            break;
803                        }
804                        keylen2++; p++; left--;
805                    }
806                }
807                if (keylen2 != keylen) fatal("wtrig2/collectionterminverteddb/keylen");
808                if (memcmp(fldarea,fldp2,keylen)) fatal("wtrig2/collectionterminverteddb/key");
809
810                if (parmtrace & 0x04) printf(" 4|%"_LD_"|%s|%"_LD_"|%f\n",docmfn,table+dochidx*hwidth,MFRmfn,weight);
811
812                /* loop through term's postings and OR the mfn's bit */
813                if (readwritebin) {
814                    int n=sizeof(hitmfn);
815                    for (dirp2=MFRdir, xdir2=0, loop=MFRnvf; loop--; dirp2++, xdir2++) {
816                        if (dirp2->tag != TAG5) continue;
817                        left=dirp2->len;
818                        if (left < n*nmfns) fatal("wtrig2/collectionterminverteddb/bin/left/1");
819                        for (p=FIELDP(xdir2); left; ) {
820                            memcpy((void *)&hitmfn,p,n);
821                            p+=n; left-=n;
822                            if (left < 0) fatal("wtrig2/collectionterminverteddb/bin/left/2");
823                            if (hitmfn < 1) fatal("wtrig2/collectionterminverteddb/bin/mfn invalid/1");
824                            if (hitmfn > COLLECTION_SIZE) {
825                                fatal("wtrig2/collectionterminverteddb/bin/mfn invalid/2");
826                            }
827                            hitmask =hitbitmask[hitmfn&BY8RMASK];
828                            hitoffset = hitmfn/8;
829#if PARMLANG
830                            /* filter language hits */
831                            if (langidx >= 0) {
832                                unsigned char c = *(langshits[langidx]+hitoffset);
833                                if (c & hitmask)
834                                    HITS[hitoffset] |= hitmask;
835                            }
836                            else
837#endif /* PARMLANG */
838                            HITS[hitoffset] |= hitmask;
839                            if (parmtrace & 0x08) printf(" 8|%"_LD_"|%s|%"_LD_"|%"_LD_"|%d/%d/%d|%d/%"_LD_"\n",docmfn,table+dochidx*hwidth,hitmfn,MFRmfn,loop,xdir,left,n,nmfns);
840                        }
841                        break;
842                    } /* end term postings */
843                }
844                else {
845                    for (dirp2=MFRdir, xdir2=0, loop=MFRnvf; loop--; dirp2++, xdir2++) {
846                        if (dirp2->tag != TAG5) continue;
847                        for (hitmfn=0, p=FIELDP(xdir2), left=dirp2->len; left; ) {
848                            if (!isdigit(*p)) break;
849                            hitmfn=hitmfn*10+((int)(*p)-(int)'0');
850                            p++; left--;
851                        }
852                        if (hitmfn < 1) fatal("wtrig2/collectionterminverteddb/mfn invalid/1");
853                        if (hitmfn > COLLECTION_SIZE) fatal("wtrig2/collectionterminverteddb/mfn invalid/2");
854                        hitmask =hitbitmask[hitmfn&BY8RMASK];
855                        hitoffset = hitmfn/8;
856#if PARMLANG
857                            /* filter language hits */
858                            if (langidx >= 0) {
859                                unsigned char c = *(langshits[langidx]+hitoffset);
860                                if (c & hitmask)
861                                    HITS[hitoffset] |= hitmask;
862                            }
863                            else
864#endif /* PARMLANG */
865                        HITS[hitoffset] |= hitmask;
866                        if (parmtrace & 0x08) printf(" 8|%"_LD_"|%s|%"_LD_"\n",docmfn,table+dochidx*hwidth,hitmfn);
867                    } /* end term postings */
868                } /* end if parmwritebin */
869            } /* end if RECrc == RCNORMAL */
870
871            recp=keeprecp; /* restore current recp */
872
873        } /* end loop term vector elements for HIT construction */
874
875
876        /* loop throught hit records and process against the corresponding vector WEIGHT[0..nterms-1]
877        */
878        for (hitmfn=1; hitmfn <= COLLECTION_SIZE; hitmfn++) {
879
880            VECTEL *v;
881            LONGX cnt=0;
882
883            if (*collectionterminverteddb) {
884                hitmask = hitbitmask[hitmfn&BY8RMASK];
885                hitoffset = hitmfn/8;
886                if (hitoffset >= hitbytes) break;
887                if (!(HITS[hitoffset] & hitmask)) continue;
888            }
889
890            if (parmtrace & 0x10) printf("16|%"_LD_"|%"_LD_"\n",docmfn,hitmfn);
891
892            /* convert hitmfn to its original mfn */
893            collhitmfn=hitmfn;
894
895            /* get correspoding vector */
896            if (parmloadvectors) {
897                v=VECTORS+VECTOFF[hitmfn-1]; cnt=VECTCNT[hitmfn-1];
898                if (parmcollmfntag) collhitmfn=VECTCMF[hitmfn-1];
899            }
900            else {
901                 /* RECORD  */
902                RECSTRU *recp;
903                DIRSTRU *dirp;
904                int xdir;
905                FFI loop,left;
906                v=vector;
907                RECORD(irectv,collectiontermvectorsdb,hitmfn);
908
909                if (readwritebinv) {
910                    if (fldupdat(irectv,"Gsplit=4=wtrig")) fatal("wtrig2/readvectors/Gsplit");
911                }
912
913                for (dirp=MFRdir, xdir=0, loop=MFRnvf; loop--; dirp++, xdir++) {
914                    if (dirp->tag == parmcollmfntag) {
915                        for (collhitmfn=0, p=FIELDP(xdir), left=dirp->len; left; ) {
916                            if (!isdigit(*p)) break;
917                            collhitmfn=collhitmfn*10+((int)(*p)-(int)'0');
918                            p++; left--;
919                        }
920                        if (collhitmfn < 1) fatal("wtrig2/readvectors/mfn invalid/1");
921                        //if (collhitmfn > COLLECTION_SIZE) fatal("wtrig2/readvectors/mfn invalid/2"); /* AOT, 11/05/2004 */
922                    }
923                    if (dirp->tag != TAG4) continue;
924                    if (cnt >= readmaxtv) break;
925                    for (keylen=0, p=fldp=FIELDP(xdir), left=dirp->len; left; ) {
926                        if (*p == '^') break;
927                        keylen++; p++; left--;
928                    }
929                    if (left > 2) if (*p++ == '^') if (*p++ == 'w') {  /* ^w */
930                        v->weight=atof(p);
931                    }
932                    v->hidx=bsrchindex(table,tabentries,readwidth,fldp,keylen,&found);
933                    if (!found) fatal("wtrig2/getvector/TAG4/not found");
934                    if (parmtrace & 0x20) printf("32|%"_LD_"|%"_LD_"|%s|%f\n",docmfn,hitmfn,table+v->hidx*hwidth,v->weight);
935                    v++; cnt++;
936                }
937                v=vector; /* init VW while */
938            } /* end parmloadvectors */
939
940
941            /* compute similarity between input document and collection doc
942            */
943                        somaprod=0; /* init sum of products of corresponding terms */
944            somaq=0;    /* init sum of squares for collection doc terms */
945            for (; cnt--; v++) {
946                float W;
947                if (v->hidx < 0 || v-> hidx >= readnterms) fatal("wtrig2/VW/hidx");
948
949                somaq += v->weight * v->weight; /* sum of squares for collection doc terms */
950
951                W=WEIGHT[v->hidx];
952                if (!W) continue;
953
954                somaprod += W * v->weight; /* sum of products of corresponding terms */
955            }
956
957            simil=0;
958            if (somaprod) {
959
960                float denom = sqrt( Wsomaq * somaq);  /* compute */
961
962                            if (denom > 0) simil=somaprod/denom;    /* compute */
963
964                if (simil > 1.0) simil=1.0;   /* esteban, 09/12/2003 */
965               
966            } /* end if somaprod */
967
968            /* output results
969            */
970            if (simil >= parmminsim) if (simil <= parmmaxsim) {
971
972              if (parmcollapse) { /* collapse */
973                if (simil > collapsesim1) {
974                    collapsesim1=simil;
975                    collapsemfn1=collhitmfn;
976                    collapsehit1=hitmfn;
977                    if (parmtrace & 0x40) printf("64|%"_LD_"|%"_LD_"|%"_LD_"|%f\n",docmfn,collhitmfn,hitmfn,simil);
978                }
979              }
980              else { /* not collapse */
981                /* mantain list of related */
982                LISTA *l=NULL;
983                LISTA *prev=NULL;
984                LONGX nextm=0; /* flag */
985
986                if (listhdr->mfn) l=listhdr;
987                while (l) {
988                    if (simil < l->sim) { prev=l; l=l->next; }
989                    else break;
990                }
991                nextm=((l)?l->mfn:0);
992                if (listavail) {
993                        LISTA *newl=listavail;
994                        listavail=listavail->avail;
995                        newl->sim=simil; newl->mfn=collhitmfn; /**/newl->xxx=docmfn;/**/ newl->hit=hitmfn;
996                        newl->prev=prev;
997                        newl->next=l;
998                        if (prev) prev->next=newl;
999                        if (nextm) l->prev=newl;
1000                        if (!newl->prev) listhdr=newl;
1001                        if (!newl->next) listtail=newl;
1002                        if (parmtrace2) printf("64a|");
1003                }
1004                else {
1005                    if (simil > listtail->sim) {
1006                        LISTA *last=listtail;
1007                        LISTA *repl=last;
1008                        LISTA *lnext=NULL;
1009                        if (l) lnext=l->next;
1010                        if (last->prev) {
1011                            listtail=last->prev;
1012                            listtail->next=NULL;
1013                        }
1014                        repl->sim=simil; repl->mfn=collhitmfn; /**/repl->xxx=docmfn;/**/ repl->hit=hitmfn;
1015                        repl->prev=prev;
1016                        if (prev) prev->next=repl;
1017                        if (l) if (lnext) {
1018                            repl->next=l;
1019                            l->prev=repl;
1020                        }
1021                        if (!repl->prev) listhdr=repl;
1022                        if (!repl->next) listtail=repl;
1023                        if (parmtrace2) printf("64b|");
1024                    }
1025                }
1026                if (parmtrace2) {
1027                  for (l=listhdr; l; l=l->next) {
1028                    if (!l) break;
1029                    //printf("%"_LD_"|%"_LD_"|%f  p=%"_LD_"|n=%"_LD_"|a=%"_LD_"  hdr=%"_LD_" lst=%"_LD_" prev=%"_LD_"\n",docmfn,l->mfn,l->sim,
1030                    printf("%"_LD_"|%"_LD_"|%"_LD_"|%f  p=%"_LD_"|n=%"_LD_"|a=%"_LD_"  hdr=%"_LD_" lst=%"_LD_"\n",docmfn,l->mfn,l->hit,l->sim,
1031                      (l->prev)?((LISTA *)(l->prev))->mfn:-1,
1032                      (l->next)?((LISTA *)(l->next))->mfn:-1,
1033                      (l->avail)?((LISTA *)(l->avail))->mfn:-1,
1034                      (listhdr->mfn)?listhdr->mfn:-1,
1035                      (listtail->mfn)?listtail->mfn:-1);
1036                      //,(prev)?prev->mfn:-1);
1037                  }
1038                }
1039                if (parmtrace & 0x40) printf("64|%"_LD_"|%"_LD_"|%"_LD_"|%f\n",docmfn,collhitmfn,hitmfn,simil);
1040              } /* end collapse */
1041
1042            } /* end if sim>=<= */
1043
1044        } /* end loop throught hit records and process the corresponding vector */
1045
1046        /* output related collection docs for the document
1047        */
1048        if (*outsimilardb) {
1049            RECSTRU *recp;
1050            LISTA *l;
1051            char *batchp=buff;
1052            buff[0]='\0';
1053            if (parmcollapse) { /* collapse */
1054                LONGX mfncollapse;
1055                /* get output mfn, from tag parmcollapse of <mf1>.v */
1056                mfncollapse=atol(recfield(buff,irec,parmcollapse,1,""));
1057                if (mfncollapse < currentmfncollapsed) fatal("wtrig2/outsimilardb/documenttermvectorsdb/mfn");
1058                /* collapse results */
1059                if (mfncollapse == currentmfncollapsed) if (collapsemfn1) {
1060                    /* mantain list of related */
1061                    LISTA *l=listhdr;
1062                    LISTA *prev=NULL;
1063                    while (l) {
1064                        if (collapsemfn1 == l->mfn) {
1065                            if (collapsesim1 > l->sim) {
1066                                /* remove from list */
1067                                LISTA *next=l->next;
1068                                LISTA *prev=l->prev;
1069                                if (prev) prev->next=l->next;
1070                                if (next) next->prev=prev;
1071                                l->sim=0.0; l->mfn=0; l->xxx=0; l->hit=0;
1072                                if (!prev) /* deletando cabeca de lista */
1073                                    if (next) listhdr=next; else listhdr=lista;
1074                                if (!next) /* deletando fim de lista */
1075                                    if (prev) listtail=prev; else listtail=lista;
1076                                l->avail=listavail; listavail=l; /* reuse it */
1077                                l=NULL; /* force add */
1078                            }
1079                            if (parmtrace2) printf("64=|\n");
1080                            break; /* l-> will remain in list */
1081                        } else l=l->next;
1082                    }
1083                    if (!l) {
1084                      /* add to list */
1085                      if (listhdr->mfn) l=listhdr;
1086                      while (l) {
1087                           if (collapsesim1 < l->sim) { prev=l; l=l->next; }
1088                           else break;
1089                      }
1090                      if (listavail) {
1091                            LISTA *newl=listavail;
1092                            LONGX nextm; /* flag */
1093                            nextm=((l)?l->mfn:0);
1094                            listavail=listavail->avail;
1095                            newl->sim=collapsesim1; newl->mfn=collapsemfn1; newl->xxx=docmfn; newl->hit=collapsehit1;
1096                            newl->prev=prev;
1097                            newl->next=l;
1098                            if (prev) prev->next=newl;
1099                            if (nextm) l->prev=newl;
1100                            if (!newl->prev) listhdr=newl;
1101                            if (!newl->next) listtail=newl;
1102                            if (parmtrace2) printf("64A|\n");
1103                      }
1104                      else {
1105                        if (collapsesim1 > listtail->sim) {
1106                            LISTA *last=listtail;
1107                            LISTA *repl=last;
1108                            LISTA *lnext=NULL;
1109                            if (l) lnext=l->next;
1110                            if (last->prev) {
1111                                listtail=last->prev;
1112                                listtail->next=NULL;
1113                            }
1114                            repl->sim=collapsesim1; repl->mfn=collapsemfn1; repl->xxx=docmfn; repl->hit=collapsehit1;
1115                            repl->prev=prev;
1116                            if (prev) prev->next=repl;
1117                            if (l) if (lnext) {
1118                                repl->next=l;
1119                                l->prev=repl;
1120                            }
1121                            if (!repl->prev) listhdr=repl;
1122                            if (!repl->next) listtail=repl;
1123                            if (parmtrace2) printf("64B|\n");
1124                        }
1125                      }
1126                    } /* end if l */
1127                    if (parmtrace2) {
1128                      for (l=listhdr; l; l=l->next) {
1129                        if (!l) break;
1130                        //printf("  |%"_LD_"|%"_LD_"|%f|%"_LD_"  p=%"_LD_"|n=%"_LD_"|a=%"_LD_"  hdr=%"_LD_" lst=%"_LD_" prev=%"_LD_" \n",docmfn,l->mfn,l->sim,l->xxx,
1131                        printf("  |%"_LD_"|%"_LD_"|%f|%"_LD_"|%"_LD_"  p=%"_LD_"|n=%"_LD_"|a=%"_LD_"  hdr=%"_LD_" lst=%"_LD_"\n",docmfn,l->mfn,l->sim,l->xxx,l->hit,
1132                          (l->prev)?((LISTA *)(l->prev))->mfn:-1,
1133                          (l->next)?((LISTA *)(l->next))->mfn:-1,
1134                          (l->avail)?((LISTA *)(l->avail))->mfn:-1,
1135                          (listhdr->mfn)?listhdr->mfn:-1,
1136                          (listtail->mfn)?listtail->mfn:-1);
1137                          //,(prev)?prev->mfn:-1);
1138                      }
1139                    }
1140                    if (parmtrace & 0x40) printf("64:|%"_LD_"|%"_LD_"|%"_LD_"|%f\n",docmfn,collapsehit1,collapsemfn1,collapsesim1);
1141                }
1142                /* output collapsed results */
1143                if (mfncollapse != currentmfncollapsed) {
1144                    buff[0]='\0';
1145                    for (l=listhdr; l; l=l->next) {
1146                        if (!l->mfn) break;
1147                        sprintf(batchp,"<6 0>%"_LD_"^s%f^m%"_LD_"^h%"_LD_"</6>",l->mfn,l->sim,l->xxx,l->hit);
1148                        batchp+=strlen(batchp);
1149                    }
1150                    if (buff[0]) {
1151                        if (fldupdat(outirec,buff)) fatal("wtrig2/outsimilardb/collapse/fldupdat");
1152                        recupdat(outcrec,outirec);
1153                    }
1154                    /* re-init list of relevant terms */
1155                    memset(lista,0x00,parmmaxrelat*sizeof(LISTA));
1156                    for (l=lista, listavail=lista+1, loop=0; (LONGX)loop<(parmmaxrelat-1); loop++, l++, listavail++)
1157                        l->avail=listavail;
1158                    listhdr=listtail=listavail=lista;
1159                    /* set current collapsed output mfn */
1160                    currentmfncollapsed=mfncollapse;
1161                    /* re-init output collapsed results record */
1162                    RECORD(outirec,outsimilardb,mfncollapse); MFRstatus=ACTIVE;
1163                }
1164            }
1165            else { /* not collapse */
1166                RECORD(outirec,outsimilardb,docmfn); MFRstatus=ACTIVE;
1167                for (l=listhdr; l; l=l->next) {
1168                    if (!l->mfn) break;
1169                    //sprintf(batchp,"<6 0>%"_LD_"^s%f</6>",l->mfn,l->sim);
1170                    sprintf(batchp,"<6 0>%"_LD_"^s%f^m%"_LD_"^h%"_LD_"</6>",l->mfn,l->sim,l->xxx,l->hit);
1171                    batchp+=strlen(batchp);
1172                }
1173                if (buff[0]) {
1174                    if (fldupdat(outirec,buff)) fatal("wtrig2/outsimilardb/fldupdat");
1175                    recupdat(outcrec,outirec);
1176                }
1177            }
1178        }
1179
1180        count++;
1181        if (parmtell) if (count%parmtell == 0) fprintf(stderr,"+++ %"_LD_"\n",count);
1182
1183    } /* end read term vector */
1184
1185
1186    /* output collapsed results last record */
1187    if (*outsimilardb) if (parmcollapse) {
1188        LISTA *l;
1189        char *batchp=buff;
1190        buff[0]='\0';
1191        for (l=listhdr; l; l=l->next) {
1192            if (!l->mfn) break;
1193            sprintf(batchp,"<6 0>%"_LD_"^s%f^m%"_LD_"^h%"_LD_"</6>",l->mfn,l->sim,l->xxx,l->hit);
1194            batchp+=strlen(batchp);
1195        }
1196        if (buff[0]) {
1197            if (fldupdat(outirec,buff)) fatal("wtrig2/outsimilardb/collapse/fldupdat");
1198            recupdat(outcrec,outirec);
1199        }
1200    }
1201
1202    /* log execution
1203    */
1204    /* ... */
1205
1206    exit(0);  /* AOT, 30/07/2004 - thanks MB */
1207
1208} /* end of main */
1209
Note: See TracBrowser for help on using the browser.