| 1 | /* ---------------------------------------------------------------- CIMSRT.C */ |
|---|
| 2 | |
|---|
| 3 | /* ---------------------------------------------------------- C HEADER FILES */ |
|---|
| 4 | #include <string.h> |
|---|
| 5 | /* #include <mem.h> */ |
|---|
| 6 | /* ------------------------------------------------------------ HEADER FILES */ |
|---|
| 7 | #include "../cisis.h" |
|---|
| 8 | #include "easyfc.h" |
|---|
| 9 | #include "easyci.h" |
|---|
| 10 | #include "cimsrt.h" |
|---|
| 11 | /* --------------------------------------------------------------- externals */ |
|---|
| 12 | extern RECSTRU *vrecp[]; /* cirun.h */ |
|---|
| 13 | extern TRMSTRU *vtrmp[]; /* cirun.h */ |
|---|
| 14 | extern char fmterrxy[]; /* cifm3.c */ |
|---|
| 15 | |
|---|
| 16 | /* ============================================================= cms_writptr */ |
|---|
| 17 | void cms_writptr(long mfn, |
|---|
| 18 | XRPTR ptr, |
|---|
| 19 | long idx) |
|---|
| 20 | { |
|---|
| 21 | DBXSTRU *dbxp; |
|---|
| 22 | long xbyte; |
|---|
| 23 | #if 1 |
|---|
| 24 | char *xryyp; |
|---|
| 25 | #else |
|---|
| 26 | char *p; |
|---|
| 27 | XRPOS xpos; |
|---|
| 28 | #endif |
|---|
| 29 | XRPOS thispos; |
|---|
| 30 | int thisidx; |
|---|
| 31 | long wcomb; |
|---|
| 32 | int wcomp; |
|---|
| 33 | static int changed=0; |
|---|
| 34 | |
|---|
| 35 | dbxp = VRECdbxp(idx); |
|---|
| 36 | |
|---|
| 37 | thispos = (mfn+XRMAXTV1) / XRMAXTIV; |
|---|
| 38 | |
|---|
| 39 | #if 0 /* 1 */ |
|---|
| 40 | if (changed && (mfn <= 0 || labs(DBXxribp->xrxrpos) != thispos)) { |
|---|
| 41 | xpos=labs(DBXxribp->xrxrpos); |
|---|
| 42 | xbyte=(long)((xpos-1)<<XRSHIFT); |
|---|
| 43 | if (lseek(DBXxropn,xbyte,SEEK_SET) != xbyte) |
|---|
| 44 | fatal("msrt/writptr/seek/break"); |
|---|
| 45 | #if CNV_PCBINUM |
|---|
| 46 | memcpy(cnv_pcbuff,DBXxribp,XRBSIZ); |
|---|
| 47 | ConvertXRF_REC(cnv_pcbuff); |
|---|
| 48 | if (CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ) != XRBSIZ) |
|---|
| 49 | #else |
|---|
| 50 | if (CIWRITE(DBXxropn,(char *)DBXxribp,XRBSIZ) != XRBSIZ) |
|---|
| 51 | #endif |
|---|
| 52 | fatal("msrt/writptr/write/break"); |
|---|
| 53 | if (mfn <= 0) return; |
|---|
| 54 | } |
|---|
| 55 | #endif /* 1 */ |
|---|
| 56 | |
|---|
| 57 | recxref(vrecp[idx],mfn,&wcomb,&wcomp); /* already buffered */ |
|---|
| 58 | if (labs(DBXxribp->xrxrpos) != thispos) fatal("msrt/writptr/thispos"); |
|---|
| 59 | thisidx = (mfn-1)%XRMAXTIV; |
|---|
| 60 | DBXxribp->xrmfptr[thisidx] = ptr; |
|---|
| 61 | changed = 1; |
|---|
| 62 | |
|---|
| 63 | if (!DBXxryyp) fatal("msrt/writptr/xryyp"); |
|---|
| 64 | xbyte=(long)((thispos-1)<<XRSHIFT); |
|---|
| 65 | xryyp=DBXxryyp+xbyte; |
|---|
| 66 | ((XRSTRU *)xryyp)->xrmfptr[thisidx] = ptr; |
|---|
| 67 | |
|---|
| 68 | #if 1 |
|---|
| 69 | return; |
|---|
| 70 | #else |
|---|
| 71 | xbyte=(long)( ((thispos-1)<<XRSHIFT)+XRPOSSIZ+thisidx*XRPTRSIZ ); |
|---|
| 72 | if (lseek(DBXxropn,xbyte,0) != xbyte) |
|---|
| 73 | fatal("msrt/writptr/seek"); |
|---|
| 74 | p = (char *)&DBXxribp->xrmfptr[thisidx]; |
|---|
| 75 | #if CNV_PCBINUM |
|---|
| 76 | ConvertXRF_PTR(p); |
|---|
| 77 | #endif |
|---|
| 78 | if (CIWRITE(DBXxropn,p,XRPTRSIZ) != XRPTRSIZ) |
|---|
| 79 | fatal("msrt/writptr/write"); |
|---|
| 80 | #endif /* 1 */ |
|---|
| 81 | } |
|---|
| 82 | /* ============================================================= cms_findptr */ |
|---|
| 83 | XRPTR cms_findptr(long mfn, |
|---|
| 84 | long idx) |
|---|
| 85 | { |
|---|
| 86 | XRPTR ptr; |
|---|
| 87 | DBXSTRU *dbxp; |
|---|
| 88 | long wcomb; |
|---|
| 89 | int wcomp; |
|---|
| 90 | |
|---|
| 91 | if (recxref(vrecp[idx],mfn,&wcomb,&wcomp) == RCEOF) return 0L; |
|---|
| 92 | dbxp = VRECdbxp(idx); |
|---|
| 93 | ptr = DBXxribp->xrmfptr[(mfn-1)%XRMAXTIV]; |
|---|
| 94 | return ptr; |
|---|
| 95 | } |
|---|
| 96 | /* ============================================================= cms_exchptr */ |
|---|
| 97 | void cms_exchptr(long i, |
|---|
| 98 | long j, |
|---|
| 99 | long idx) |
|---|
| 100 | { |
|---|
| 101 | XRPTR ptr; |
|---|
| 102 | |
|---|
| 103 | ptr = cms_findptr(i,idx); |
|---|
| 104 | cms_writptr(i,cms_findptr(j,idx),idx); |
|---|
| 105 | cms_writptr(j,ptr,idx); |
|---|
| 106 | } |
|---|
| 107 | /* ============================================================== cms_getkey */ |
|---|
| 108 | void cms_getkey(char *buff, |
|---|
| 109 | long buff_size, |
|---|
| 110 | long idx, |
|---|
| 111 | long mfn, |
|---|
| 112 | long keysize, |
|---|
| 113 | BOOLEAN fmtgen, |
|---|
| 114 | FMT_CODE *pgmp, |
|---|
| 115 | long keyField) |
|---|
| 116 | { |
|---|
| 117 | long fmtrc; |
|---|
| 118 | int i; |
|---|
| 119 | unsigned left,len; |
|---|
| 120 | char *p; |
|---|
| 121 | |
|---|
| 122 | record(idx,VRDBname(idx),mfn); |
|---|
| 123 | if (VRECrc(idx) == RCEOF) { |
|---|
| 124 | printf("*** mfn=%ld\n",mfn); |
|---|
| 125 | fatal("msrt/getkey/RCEOF"); |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | if (keyField) { |
|---|
| 129 | |
|---|
| 130 | i = fieldx(idx,(int)keyField,1); |
|---|
| 131 | memcpy(buff,VFIELDP(idx,i),VDIRlen(idx,i)); |
|---|
| 132 | *(buff+VDIRlen(idx,i)) = '\0'; |
|---|
| 133 | |
|---|
| 134 | } else { |
|---|
| 135 | |
|---|
| 136 | fmtrc = fmt_inter(pgmp,idx,buff_size,buff,buff_size); |
|---|
| 137 | if (fmtrc >= 0L && fmtgen) { |
|---|
| 138 | p = strdup(buff); |
|---|
| 139 | *buff = '\0'; |
|---|
| 140 | fmtrc = recfmt(idx,buff_size,p,buff,buff_size); |
|---|
| 141 | efc_free(p); |
|---|
| 142 | } |
|---|
| 143 | if (fmtrc < 0L) { |
|---|
| 144 | printf("*** Format RC = %ld",fmtrc); |
|---|
| 145 | fatal(fmterrxy); |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | } |
|---|
| 149 | |
|---|
| 150 | len = strlen(buff); |
|---|
| 151 | if (len > keysize) len = keysize; |
|---|
| 152 | left = keysize-len; |
|---|
| 153 | |
|---|
| 154 | if (left > 0) memset(buff+keysize-left,' ',left); |
|---|
| 155 | sprintf(buff+keysize,"%06ld",VMFRmfn(idx)); /* parmkeylen */ |
|---|
| 156 | } |
|---|
| 157 | /* =========================================================== cms_sort_list */ |
|---|
| 158 | void cms_sort_list(long regsin, |
|---|
| 159 | char *tbuf, |
|---|
| 160 | char *ibuf, |
|---|
| 161 | long buf_size, |
|---|
| 162 | long idx, |
|---|
| 163 | long keysize, |
|---|
| 164 | BOOLEAN fmtgen, |
|---|
| 165 | FMT_CODE *pgmp, |
|---|
| 166 | long keyField) |
|---|
| 167 | { |
|---|
| 168 | /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |
|---|
| 169 | - Comm ACM, v12(3) march, 1969 pp185-187 - Algorithm 347 |
|---|
| 170 | - Copied from msrt.c, original name: ordena |
|---|
| 171 | - adapted to receive local parameter instead of global ones |
|---|
| 172 | |
|---|
| 173 | 1.0 - 27.Nov.1998 |
|---|
| 174 | >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */ |
|---|
| 175 | long parmi; |
|---|
| 176 | long ii,ij,k,l,m; |
|---|
| 177 | long il[64],iu[64]; |
|---|
| 178 | long i,j; |
|---|
| 179 | XRPTR ptr; |
|---|
| 180 | |
|---|
| 181 | m = 0L; |
|---|
| 182 | il[m] = parmi = 1L; |
|---|
| 183 | iu[m] = regsin; |
|---|
| 184 | |
|---|
| 185 | while (m >= 0) { |
|---|
| 186 | |
|---|
| 187 | i = il[m]; |
|---|
| 188 | j = iu[m]; |
|---|
| 189 | m--; |
|---|
| 190 | |
|---|
| 191 | while ((j - i > 10) || (i == parmi && i < j)) { |
|---|
| 192 | ij = (i + j) / 2; /* le tbuf */ |
|---|
| 193 | cms_getkey(tbuf,buf_size,idx,ij,keysize,fmtgen,pgmp,keyField); |
|---|
| 194 | k = i; |
|---|
| 195 | l = j; |
|---|
| 196 | cms_getkey(ibuf,buf_size,idx,i,keysize,fmtgen,pgmp,keyField); |
|---|
| 197 | if (memcmp(ibuf,tbuf,keysize) > 0) { |
|---|
| 198 | cms_exchptr(ij,i,idx); |
|---|
| 199 | memcpy(tbuf,ibuf,keysize); /* t=a[ij] */ |
|---|
| 200 | } |
|---|
| 201 | cms_getkey(ibuf,buf_size,idx,j,keysize,fmtgen,pgmp,keyField); |
|---|
| 202 | if (memcmp(ibuf,tbuf,keysize) < 0) { |
|---|
| 203 | cms_exchptr(ij,j,idx); |
|---|
| 204 | memcpy(tbuf,ibuf,keysize); /* t=a[ij] */ |
|---|
| 205 | cms_getkey(ibuf,buf_size,idx,i,keysize,fmtgen,pgmp,keyField); |
|---|
| 206 | if (memcmp(ibuf,tbuf,keysize) > 0) { |
|---|
| 207 | cms_exchptr(ij,i,idx); |
|---|
| 208 | memcpy(tbuf,ibuf,keysize); /* t=a[ij] */ |
|---|
| 209 | } |
|---|
| 210 | } |
|---|
| 211 | while (TRUE) { |
|---|
| 212 | do { |
|---|
| 213 | l--; |
|---|
| 214 | cms_getkey(ibuf,buf_size,idx,l,keysize,fmtgen,pgmp,keyField); |
|---|
| 215 | } while (memcmp(ibuf,tbuf,keysize) > 0); |
|---|
| 216 | do { |
|---|
| 217 | k++; |
|---|
| 218 | cms_getkey(ibuf,buf_size,idx,k,keysize,fmtgen,pgmp,keyField); |
|---|
| 219 | } while (memcmp(ibuf,tbuf,keysize) < 0); |
|---|
| 220 | if (k <= l) { |
|---|
| 221 | cms_exchptr(l,k,idx); |
|---|
| 222 | } else |
|---|
| 223 | break; |
|---|
| 224 | } /* while */ |
|---|
| 225 | if ((j - i) <= 10) break; |
|---|
| 226 | m++; |
|---|
| 227 | if (l - i > j - k) { |
|---|
| 228 | il[m] = i; |
|---|
| 229 | iu[m] = l; |
|---|
| 230 | i = k; |
|---|
| 231 | } else { |
|---|
| 232 | il[m] = k; |
|---|
| 233 | iu[m] = j; |
|---|
| 234 | j = l; |
|---|
| 235 | } |
|---|
| 236 | } |
|---|
| 237 | for(ii = i,i++; i <= j; i++) { |
|---|
| 238 | ptr = cms_findptr(i,idx); |
|---|
| 239 | cms_getkey(tbuf,buf_size,idx,i,keysize,fmtgen,pgmp,keyField); |
|---|
| 240 | k = i - 1; |
|---|
| 241 | cms_getkey(ibuf,buf_size,idx,k,keysize,fmtgen,pgmp,keyField); |
|---|
| 242 | if (memcmp(ibuf,tbuf,keysize) > 0) { |
|---|
| 243 | do { |
|---|
| 244 | cms_writptr(k+1,cms_findptr(k,idx),idx); |
|---|
| 245 | k--; |
|---|
| 246 | if (k < ii) break; |
|---|
| 247 | cms_getkey(ibuf,buf_size,idx,k,keysize,fmtgen,pgmp,keyField); |
|---|
| 248 | } while (memcmp(ibuf,tbuf,keysize) > 0); |
|---|
| 249 | cms_writptr(k+1,ptr,idx); |
|---|
| 250 | } |
|---|
| 251 | } |
|---|
| 252 | } |
|---|
| 253 | } |
|---|
| 254 | /* ================================================================ cms_sort */ |
|---|
| 255 | BOOLEAN cms_sort(char *db, |
|---|
| 256 | long rec_size, |
|---|
| 257 | long parmkeylen, |
|---|
| 258 | FMT_CODE *fmtcode, |
|---|
| 259 | BOOLEAN fmtgen, |
|---|
| 260 | BOOLEAN parmmfn, |
|---|
| 261 | long keyField) |
|---|
| 262 | { |
|---|
| 263 | EFC_ERROR err; |
|---|
| 264 | long nxtmfn; |
|---|
| 265 | long idx; |
|---|
| 266 | long fmtkeylen; |
|---|
| 267 | char *ibuf; |
|---|
| 268 | char *tbuf; |
|---|
| 269 | char *p; |
|---|
| 270 | int n,rc; |
|---|
| 271 | DBXSTRU *dbxp; /* mandatory for defines DBX */ |
|---|
| 272 | long mfn; |
|---|
| 273 | long seek; |
|---|
| 274 | int fd; |
|---|
| 275 | long wcomb; |
|---|
| 276 | int wcomp; |
|---|
| 277 | #if CNV_PCBINUM |
|---|
| 278 | char convmfn[sizeof(mfn)]; |
|---|
| 279 | #endif |
|---|
| 280 | char *xryyp; |
|---|
| 281 | |
|---|
| 282 | nxtmfn = eci_last_mfn(&err,db)+1L; |
|---|
| 283 | if (nxtmfn < 1L) return FALSE; |
|---|
| 284 | |
|---|
| 285 | idx = eci_rec_new(&err,rec_size); |
|---|
| 286 | if (idx < 0L) return FALSE; |
|---|
| 287 | eci_rec_active(idx); |
|---|
| 288 | record(idx,db,1L); |
|---|
| 289 | |
|---|
| 290 | fmtkeylen = parmkeylen+6; /* %6ld */ |
|---|
| 291 | |
|---|
| 292 | ibuf = efc_new(rec_size); |
|---|
| 293 | tbuf = efc_new(rec_size); |
|---|
| 294 | if (!ibuf || !tbuf) return FALSE; |
|---|
| 295 | |
|---|
| 296 | mstflush(db); |
|---|
| 297 | mstsetup(db,(long)((nxtmfn/XRMAXTIV + 1) * XRBSIZ)/*loadxrf*/,0L); |
|---|
| 298 | dbxp = VRECdbxp(idx); |
|---|
| 299 | if (DBXxryyp == NULL) fatal("msrt/loadxrf/overflow"); |
|---|
| 300 | xryyp = DBXxryyp; /* keep */ |
|---|
| 301 | DBXxryyp = NULL; /* avoid FREE */ |
|---|
| 302 | mstflush(db); |
|---|
| 303 | dbxopt_ordwr = O_RDWR; |
|---|
| 304 | mstsetup(db,0L,0L); |
|---|
| 305 | DBXxryyp = xryyp; /* restore */ |
|---|
| 306 | |
|---|
| 307 | /* processing */ |
|---|
| 308 | cms_sort_list(nxtmfn-1L,tbuf,ibuf,rec_size,idx,fmtkeylen,fmtgen,fmtcode,keyField); |
|---|
| 309 | #if 0 /* 1 */ |
|---|
| 310 | cms_writptr(0,0); /* breakout */ |
|---|
| 311 | #else |
|---|
| 312 | if (!DBXxropw) fatal("msrt/xropw/break"); |
|---|
| 313 | if (lseek(DBXxropn,0L,SEEK_SET) != 0) fatal("msrt/seek/break"); |
|---|
| 314 | if (!DBXxryyp) fatal("msrt/xryyp/break"); |
|---|
| 315 | for (xryyp = DBXxryyp; ; xryyp+=XRBSIZ) { |
|---|
| 316 | #if CNV_PCBINUM |
|---|
| 317 | memcpy(cnv_pcbuff,xryyp,XRBSIZ); |
|---|
| 318 | ConvertXRF_REC(cnv_pcbuff); |
|---|
| 319 | if (CIWRITE(DBXxropn,cnv_pcbuff,XRBSIZ) != XRBSIZ) |
|---|
| 320 | #else |
|---|
| 321 | if (CIWRITE(DBXxropn,xryyp,XRBSIZ) != XRBSIZ) |
|---|
| 322 | #endif |
|---|
| 323 | fatal("msrt/write/break"); |
|---|
| 324 | if (((XRSTRU *)xryyp)->xrxrpos < 0) break; |
|---|
| 325 | } |
|---|
| 326 | #endif /* 1 */ |
|---|
| 327 | |
|---|
| 328 | /* rewrite mfn */ |
|---|
| 329 | if (parmmfn) { |
|---|
| 330 | for (mfn = 1L; ; mfn++) { /* not MFRmfn */ |
|---|
| 331 | rc = recxref(vrecp[idx],mfn,&wcomb,&wcomp); |
|---|
| 332 | if (rc == RCEOF) break; |
|---|
| 333 | if (rc == RCPDEL) continue; |
|---|
| 334 | seek = (long)((wcomb-1)<<MSBSHIFT); |
|---|
| 335 | seek += wcomp; |
|---|
| 336 | fd = DBXmsopn; |
|---|
| 337 | if (lseek(fd,seek,SEEK_SET) != seek) fatal("msrt/mfn/seek"); |
|---|
| 338 | n = sizeof(mfn); |
|---|
| 339 | p = (char *)&mfn; |
|---|
| 340 | #if CNV_PCBINUM |
|---|
| 341 | strcpy(convmfn,p); |
|---|
| 342 | ConvertBuffer(convmfn),n); |
|---|
| 343 | p = convmfn; |
|---|
| 344 | #endif |
|---|
| 345 | if (CIWRITE(fd,p,n) < n) fatal("msrt/mfn/write"); |
|---|
| 346 | } |
|---|
| 347 | } |
|---|
| 348 | |
|---|
| 349 | efc_free(ibuf); |
|---|
| 350 | efc_free(tbuf); |
|---|
| 351 | eci_rec_free(idx); |
|---|
| 352 | |
|---|
| 353 | return TRUE; |
|---|
| 354 | } |
|---|