root/tags/5.52/msrt.c

Revision 4, 13.2 kB (checked in by heitor.barbieri, 2 years ago)

Versão 5.52 do cisis (28/04/2010)

Line 
1/* Program MSRT:        sorts a master file in ascending order,
2                        according to a supplied format specification
3                        AOT, BRM 25/07/91.
4*/
5#include <stdio.h>
6#include <string.h>
7#include "cisis.h"   /* CISIS Interface header file */
8#include "cirun.h"   /* CISIS Interface runtime declarations */
9
10#define TRACE 0
11
12#if BEFORE20010109
13#define MAXFMTA (MAXMFRL)
14#define MAXFMTS (MAXMFRL)
15#endif
16
17FMT_CODE *pgmp;
18LONGX fmtkeylen;
19LONGX fmtlines;
20LONGX fmtasize;
21LONGX parmkeylen;
22char *fmtspec=NULL;
23char *ibuf;
24char *tbuf;
25LONGX irec=0L;          /* indice vrecp, para leitura */
26LONGX incount=0;                /* recs in */
27int parmtrace=0;        /* trace */
28LONGX parmtell=0;       /* tell */
29int parmmfn=1;          /* update mfn */
30int usetag=0;           /* do not use format */
31int parmdel=0;          /* delete duplicate keys */
32#if BEFORE20010109
33LONGX recbyts=MAXMFRL;
34#endif
35/* prototypes */
36#if ANSI
37void getkey(UBYTE *buff, LONGX mfn);
38XRPTR findptr(LONGX i);
39void writptr(LONGX i, XRPTR ptr);
40void exchptr(LONGX i, LONGX j);
41void ordena(LONGX regsin);
42#else
43void getkey();
44XRPTR findptr();
45void writptr();
46void exchptr();
47void ordena();
48#endif
49void main(argc,argv)
50int argc;
51char *argv[];
52{
53    RECSTRU *recp;      /* mandatory for defines REC,MFR,DIR,FIELDP */
54    int iarg;
55    char *p,*p1,*p2;
56    char *dbnp,*fmtp;
57    int n,rc,x;
58    LONGX nxtmfn;
59    DBXSTRU *dbxp;      /* mandatory for defines DBX */
60    LONGX mfn;
61    off_t seek;
62    int fd;
63    LONGX wcomb;
64    int wcomp;
65#if CNV_PCBINUM
66    char convmfn[sizeof(mfn)];
67#endif
68    LONGX loadxrf=0;
69    char *xryyp;
70    LONGX xpos;
71    LONGX nbytes;
72
73    if (argc < 4) {
74        printf("%s",cicopyr("Utility MSRT"));
75        printf(" \n");
76        printf("msrt <dbname> <keylen> <keyfmt> [-mfn] [tell=<n>] \n");
77        printf(" \n");
78        printf(" <dbname> master file to be sorted in place");
79        printf(" or <dbn>,<%ld> \n",loadxrf);
80        printf(" <keylen> sort key length \n");
81        printf(" <keyfmt> format specification to generate sort keys");
82        printf(" or tag=<n> \n");
83        printf(" \n");
84        printf(" -mfn     keep the original MFNs \n");
85        printf(" +del     delete duplicate tag=<n> keys \n");
86        printf(" tell=<n> produce a message to the stderr every each <n>");
87        printf(" keys \n");
88        printf(" \n");
89        exit(1);
90    }
91
92    dbnp=argv[1];
93    p=strchr(dbnp,',');
94    if (p) { 
95        *p++='\0'; 
96        if (sscanf(p,"%ld",&loadxrf) != 1) fatal(dbnp);
97    }
98
99    if (sscanf(argv[2],"%ld",&parmkeylen) != 1) fatal(argv[2]);
100
101    fmtp=argv[3];
102
103    if (strncmp(fmtp,"tag=",4) == 0) {usetag=1; fmtp+=4;}
104
105    for (iarg=4; iarg < argc; iarg++) {
106        p=argv[iarg];
107        if (strcmp(p,"trace") == 0) {
108            parmtrace=1;
109            continue;
110        }
111        if (strcmp(p,"-mfn") == 0) {
112            parmmfn=0;
113            continue;
114        }
115        if (strncmp(p,"tell=",5) == 0) {
116            if (sscanf(p+5,"%ld",&parmtell) != 1) fatal(p);
117            continue;
118        }
119        if (usetag && strcmp(p,"+del") == 0) {
120            parmdel=1;
121            continue;
122        }
123    }
124
125    /* get format */
126    if (usetag) {
127        if (sscanf(fmtp,"%d",&usetag) != 1) fatal(fmtp);
128        if (usetag < 1) fatal(fmtp);
129    }
130    else {
131#if BEFORE20010109
132        fmtspec=loadfile(dbnp,'@',fmtp,fmtspec,MAXFMTS,'\0');
133#else
134        fmtspec=loadfile(dbnp,'@',fmtp,fmtspec,0L,'\0');
135#endif
136        if (!fmtspec) fatal(fmtp);
137        if (parmtrace) {
138            showcore("+++fmt");
139            printf("+++fmt=�"); printf("%s",fmtspec); printf("�\n");
140        }
141        if (fmt_gener(&pgmp,fmtspec) < 0L) fatal(fmtspec+fmt_errof);
142    }
143
144    /* set up processing */
145#if CIWTF                                /* WTFUN support */             
146    /* setup wtfnew
147    */
148    //p=NULL;
149    //for (i=argnext; i < argc; i++) if (strncmp(argv[i],"cipar?",6) == 0 || strncmp(argv[i],"cipar=",6) == 0) { p=argv[i]+6; break; }
150    //if (!ciawtfp) if (p) if (*(p+6)) if (dbxciset(p+6)) fatal(p);
151    if (!ciawtfp) if (dbxciset("msrt.cip")) dbxciset(NULL); // optional msrt.cip
152    if (!ciawtfp) fatal("msrt/ciawtfp");
153#endif //CIWTF   
154
155    dbxstorp(dbnp); /* dbxinit ok */
156    recallok(irec,rec_maxmfrl);
157
158
159    RECORD(irec,dbnp,0L);
160    nxtmfn=MF0nxtmfn;
161
162    fmtkeylen=parmkeylen+6; /* %6ld */
163    if (fmtkeylen >= ALLOMAXV) fatal("msrt/keylen/overflow");
164
165#if BEFORE20010109
166    nbytes=MAXFMTA;
167#else
168    nbytes=RECnbytes;
169#endif
170    if (usetag) nbytes=fmtkeylen;
171
172    if ((ibuf=(char *)ALLOC((ALLOPARM)(nbytes+1))) == NULL)
173        fatal("msrt/ALLOC/ibuf");
174
175    if ((tbuf=(char *)ALLOC((ALLOPARM)(nbytes+1))) == NULL)
176        fatal("msrt/ALLOC/tbuf");
177
178    if (!loadxrf) loadxrf = (MF0nxtmfn/XRMAXTIV + 1 ) * XRBSIZ; /* 127 */
179    mstflush(dbnp);
180    n=rectrace; if (parmtrace) rectrace=1;
181    mstsetup(dbnp,loadxrf,0L);
182    rectrace=n;
183    if (parmtrace) printf("+++ loadxrf=%ld \n",loadxrf);
184    dbxp=RECdbxp;
185    if (DBXxryyp == NULL) fatal("msrt/loadxrf/overflow");
186    xryyp=DBXxryyp; /* keep */
187    DBXxryyp=NULL;  /* avoid FREE */
188    mstflush(dbnp);
189    dbxopt_ordwr=O_RDWR;
190    mstsetup(dbnp,0L,0L);
191    DBXxryyp=xryyp; /* restore */
192
193    /* processing */
194    ordena(nxtmfn-1);
195#if 0 /* 1 */
196    writptr(0,0); /* breakout */
197#else
198    if (!DBXxropw) fatal("msrt/xropw/break");
199    if (LSEEK64(DBXxropn,0L,SEEK_SET) != 0) fatal("msrt/seek/break");
200    if (!DBXxryyp) fatal("msrt/xryyp/break");
201    for (xryyp=DBXxryyp, xpos=1; ; xpos++, xryyp+=XRBSIZ) {
202#if CNV_PCBINUM
203        memcpy(cnv_pcbuff,xryyp,XRBSIZ);
204        ConvertXRF_REC(cnv_pcbuff);
205        if (CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ) != XRBSIZ)
206#else
207        if (CIWRITE(DBXxropn,xryyp,XRBSIZ) != XRBSIZ)
208#endif
209            fatal("msrt/write/break");
210        if (((XRSTRU *)xryyp)->xrxrpos < 0) break;
211    }
212#endif /* 1 */
213
214
215    /* rewrite mfn */
216    if (parmmfn) {
217        for (mfn=1L; ; mfn++) { /* not MFRmfn */
218            rc=recxref(recp,mfn,&wcomb,&wcomp);
219            if (parmtell)
220                if (mfn % parmtell == 0)
221                    printf("+++ mfn/mfn %ld \n",mfn);
222            if (rc == RCEOF) break;
223            if (rc == RCPDEL) continue;
224            seek = (off_t)((wcomb-1)<<MSBSHIFT);
225            seek += wcomp;
226            fd=DBXmsopn;
227            if (LSEEK64(fd,seek,SEEK_SET) != seek) fatal("msrt/mfn/seek");
228            n=sizeof(mfn);
229#if TRACEW
230if (parmtrace)
231printf("+++ mfn/fd,seek,write=%d,%"P_OFF_T",%d\n",fd,(LONG_LONG)seek,n);
232#endif
233            p=(char *)&mfn;
234#if CNV_PCBINUM
235            strcpy(convmfn,p);
236            ConvertBuffer(convmfn),n);
237            p=convmfn;
238#endif
239            if (CIWRITE(fd,p,n) < n) fatal("msrt/mfn/write");
240        }
241    }
242
243    /* "delete" key */
244    if (parmdel) {
245        tbuf[0]='\0'; p1=tbuf; p2=ibuf;
246        for (mfn=1L; ; mfn++) {
247            rc=recxref(recp,mfn,&wcomb,&wcomp);
248            if (rc == RCEOF) break;
249            if (rc == RCPDEL) continue;
250            if (parmtell)
251                if (mfn % parmtell == 0)
252                    printf("+++ del/mfn %ld \n",mfn);
253            getkey(p2,mfn);
254            if (memcmp(p1,p2,(unsigned)parmkeylen) == 0) {
255                x=fieldx(irec,usetag,1);
256                if (x < 0) continue;
257                seek = (off_t)((wcomb-1)<<MSBSHIFT);
258                seek += wcomp;
259                seek += LEADER + x*sizeof(DIRSTRU);
260                fd=DBXmsopn;
261#if TRACEW
262if (parmtrace)
263printf("+++ del/fd,seek,write=%d,%"P_OFF_T",%d\n",fd,(LONG_LONG)seek,n);
264#endif
265                if (LSEEK64(fd,seek,SEEK_SET) != seek) fatal("msrt/del/seek");
266                DIRtag(x)=0; 
267                p=(char *)&DIRtag(x); n=sizeof(DIRtag(x));
268                if (CIWRITE(fd,p,n) < n) fatal("msrt/del/write");
269            } 
270            else {
271                p=p1; p1=p2; /* last key */
272                p2=p; /* next key */
273            }
274        }
275    }
276
277    exit(0);
278
279} /* end of main */
280
281
282void getkey(buff,mfn)
283UBYTE *buff;
284LONGX mfn;
285{
286    RECSTRU *recp;      /* mandatory for defines REC,MFR,DIR,FIELDP */
287    char *fmtarea;
288    LONGX fmtrc;
289    int x;
290    unsigned left,keysize,len;
291
292    keysize=(unsigned)parmkeylen;
293   
294    RECORD(irec,VRDBname(irec),mfn);
295    incount++;
296    if (RECrc == RCEOF) {
297        fprintf(stderr,"*** mfn=%ld\n",mfn);
298        fatal("msrt/getkey/RCEOF");
299    }
300    fmtarea=buff;
301
302    if (usetag) {
303        x=fieldx(irec,usetag,1);
304        if (x < 0) {
305            memset(fmtarea,(int)' ',keysize);
306            left=0;
307        }
308        else {
309            len=DIRlen(x); if (len > keysize) len=keysize;
310            memcpy(fmtarea,FIELDP(x),len);
311            left=keysize-len;
312        }
313    }
314    else {
315#if BEFORE20010109
316        fmtrc=fmt_inter(pgmp,irec,(LONGX)MAXFMTA,fmtarea,(LONGX)MAXFMTA);
317#else
318        fmtrc=fmt_inter(pgmp,irec,(LONGX)RECnbytes,fmtarea,(LONGX)RECnbytes);
319#endif
320        if (fmtrc < 0L) {
321            fprintf(stderr,"*** Format RC = %ld",fmtrc);
322            fatal(fmtspec);
323        }
324        len=strlen(fmtarea); if (len > keysize) len=keysize;
325        left=keysize-len;
326    }
327
328    if (left > 0) memset(fmtarea+keysize-left,' ',left);
329    sprintf(fmtarea+keysize,"%06ld",VMFRmfn(irec)); /* parmkeylen */
330   
331    if (parmtrace) if (!usetag) printf("%s\n",fmtarea);
332    if (parmtell)
333        if (incount % parmtell == 0)
334            printf("+++ getkey=%ld\n",incount);
335}
336
337
338XRPTR findptr(i)
339LONGX i;
340{
341    XRPTR ptr;
342    DBXSTRU *dbxp;
343    RECSTRU *recp;
344    LONGX mfn;
345    LONGX wcomb;
346    int wcomp;
347    recp=vrecp[irec];
348    dbxp=RECdbxp;
349    mfn=i;
350    if (recxref(recp,mfn,&wcomb,&wcomp) == RCEOF)
351        return(0L);
352    ptr=DBXxribp->xrmfptr[(mfn-1)%XRMAXTIV];
353    return(ptr);
354}
355
356
357void writptr(i,ptr)
358LONGX i;
359XRPTR ptr;
360{
361    RECSTRU *recp;      /* elemento de vrecp, para info */
362    DBXSTRU *dbxp;
363    LONGX mfn;
364    off_t xbyte;
365#if 1
366    char *xryyp;
367#else
368    char *p;
369    XRPOS xpos;
370#endif
371    XRPOS thispos;
372    int thisidx;
373    LONGX wcomb;
374    int  wcomp;
375    static int changed=0;
376
377    recp=vrecp[irec];
378    dbxp=RECdbxp;
379    mfn=i;
380
381    thispos=    (mfn+XRMAXTV1)/XRMAXTIV;
382
383#if 0 /* 1 */
384    if (changed && (mfn <= 0 || labs(DBXxribp->xrxrpos) != thispos)) {
385        xpos=labs(DBXxribp->xrxrpos);
386        xbyte=(LONGX)((xpos-1)<<XRSHIFT);
387        if (LSEEK64(DBXxropn,xbyte,SEEK_SET) != xbyte)
388            fatal("msrt/writptr/seek/break");
389#if CNV_PCBINUM
390        memcpy(cnv_pcbuff,DBXxribp,XRBSIZ);
391        ConvertXRF_REC(cnv_pcbuff);
392        if (CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ) != XRBSIZ)
393#else
394        if (CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ) != XRBSIZ)
395#endif
396            fatal("msrt/writptr/write/break");
397        if (mfn <= 0) return;
398    }
399#endif /* 1 */
400
401    recxref(recp,mfn,&wcomb,&wcomp); /* already buffered */
402    if (labs(DBXxribp->xrxrpos) != thispos) fatal("msrt/writptr/thispos");
403    thisidx=    (mfn-1)%XRMAXTIV;
404    DBXxribp->xrmfptr[thisidx] = ptr;
405    changed=1;
406
407    if (!DBXxryyp) fatal("msrt/writptr/xryyp");
408    xbyte=(LONGX)((thispos-1)<<XRSHIFT);
409    xryyp=DBXxryyp+xbyte;
410    ((XRSTRU *)xryyp)->xrmfptr[thisidx] = ptr;
411
412#if 1
413    return;
414#else
415    xbyte=(LONGX)( ((thispos-1)<<XRSHIFT)+XRPOSSIZ+thisidx*XRPTRSIZ );
416    if (LSEEK64(DBXxropn,xbyte,0) != xbyte)
417        fatal("msrt/writptr/seek");
418    p=(char *)&DBXxribp->xrmfptr[thisidx];
419#if CNV_PCBINUM
420    ConvertXRF_PTR(p);
421#endif
422    if (CIWRITE(DBXxropn,p,XRPTRSIZ) != XRPTRSIZ)
423        fatal("msrt/writptr/write");
424#if TRACE
425printf("+++writptr - now %ld = %ld\n",mfn,(LONGX)ptr);
426#endif
427#endif /* 1 */
428}
429
430
431void exchptr(i,j)
432LONGX i;
433LONGX j;
434{
435    XRPTR ptr;
436    ptr=findptr(i);
437    writptr(i,findptr(j));
438    writptr(j,ptr);
439}
440
441
442void ordena(regsin)
443LONGX regsin;
444/* Comm ACM, v12(3) march, 1969 pp185-187 - Algorithm 347 */
445{
446    LONGX parmi;
447    LONGX ii,ij,k,l,m;
448    LONGX il[64],iu[64];
449    LONGX i,j;
450    unsigned keysize;
451    XRPTR ptr;
452
453    keysize=(unsigned)fmtkeylen;
454
455    m=0; il[m]=(parmi=1L); iu[m]=regsin;
456    while (m >= 0){
457        i = il[m]; j = iu[m]; m = m - 1;
458#if TRACE
459printf("+++desempilhou %ld - %ld\n",i,j);
460#endif
461        while ((j - i > 10) || (i == parmi && i < j)){
462            ij = (i + j) / 2; /* le tbuf */
463#if TRACE
464printf("+++particionando %ld - %ld - %ld\n",i,ij,j);
465#endif
466            getkey(tbuf,ij);
467#if TRACE
468printf("+++1. leu ij %ld: %s",ij,tbuf);
469#endif
470            k = i;  l = j;
471            getkey(ibuf,i);
472#if TRACE
473printf("+++2. leu i  %ld: %s",i,ibuf);
474#endif
475            if (memcmp(ibuf,tbuf,keysize) > 0) {
476                exchptr(ij,i);
477                memcpy(tbuf,ibuf,keysize); /* t=a[ij] */
478#if TRACE
479printf("+++2. copiou: %s",tbuf);
480#endif
481            }
482            getkey(ibuf,j);
483#if TRACE
484printf("+++3. leu j  %ld: %s",j,ibuf);
485#endif
486            if(memcmp(ibuf,tbuf,keysize) < 0) {
487                exchptr(ij,j);
488                memcpy(tbuf,ibuf,keysize); /* t=a[ij] */
489#if TRACE
490printf("+++3. copiou: %s",tbuf);
491#endif
492                getkey(ibuf,i);
493#if TRACE
494printf("+++4. leu i  %ld: %s",i,ibuf);
495#endif
496                if (memcmp(ibuf,tbuf,keysize) > 0) {
497                    exchptr(ij,i);
498                    memcpy(tbuf,ibuf,keysize); /* t=a[ij] */
499#if TRACE
500printf("+++4. copiou: %s",tbuf);
501#endif
502                }
503            }
504            while(1){
505#if TRACE
506printf("+++central: %s",tbuf);
507#endif
508                do{
509                    l = l - 1;
510                    getkey(ibuf,l);
511#if TRACE
512printf("+++l=%4ld: %s",l,ibuf);
513#endif
514                } while (memcmp(ibuf,tbuf,keysize) > 0);
515                do{
516                    k = k + 1;
517                    getkey(ibuf,k);
518#if TRACE
519printf("+++k=%4ld: %s",k,ibuf);
520#endif
521                } while (memcmp(ibuf,tbuf,keysize) < 0);
522                if (k <= l) {
523                    exchptr(l,k);
524                }
525                else
526                    break;
527            }
528            if ( (j - i) <= 10)
529                break;
530            m = m + 1;
531            if ( l - i > j - k){
532#if TRACE
533printf("+++vai empilhar %ld,%ld\n",i,l);
534#endif
535                il[m] = i; iu[m] = l; i = k;
536            }
537            else{
538#if TRACE
539printf("+++vai empilhar %ld,%ld\n",k,j);
540#endif
541                il[m] = k; iu[m] = j; j = l;
542            }
543        }
544#if TRACE
545printf("+++vai ordenar %ld - %ld\n",i,j);
546#endif
547        for(ii=i, i = i + 1; i <= j; i++){
548            ptr=findptr(i);
549            getkey(tbuf,i);
550#if TRACE
551printf("+++     i=%4ld: %s",i,tbuf);
552#endif
553            k = i - 1;
554            getkey(ibuf,k);
555#if TRACE
556printf("+++     k=%4ld: %s",k,ibuf);
557#endif
558            if (memcmp(ibuf,tbuf,keysize) > 0){
559                do {
560                    writptr(k+1,findptr(k)); k = k - 1;
561                    if (k < ii)
562                        break;
563                    getkey(ibuf,k);
564#if TRACE
565printf("+++     k %4ld: %s",k,ibuf);
566#endif
567                } while (memcmp(ibuf,tbuf,keysize) > 0);
568                writptr(k+1,ptr);
569            }
570        }
571    }
572    return;
573}
Note: See TracBrowser for help on using the browser.