📄 sort.c
字号:
if (f->kf_seq == 'D')
{ cmpl ^= 1;
*d++ = ~tmp;
}
else
*d++ = tmp;
for (i=1; i < f->kf_size; i++)
{ if (cmpl)
*d++ = ~*s--;
else
*d++ = *s--;
}
break;
default: break;
}
f = f->kf_next;
}
}
/*
* sort_merge - Do the merge
*/
sort_merge()
{
if (sort_state != SORT_OPEN)
sort_error("Merge Called Out of Sequence");
if (!sort_rec_cnt)
{ sort_state = SORT_EOF;
return;
}
merge_init();
while (sort_state != SORT_DONE)
{ lseek(sfile2, 0L, 0);
lseek(sfile3, 0L, 0);
sort_merge_cnt = 0;
sort_next_fpos = 0;
sbuf3.sb_radr = sbuf3.sb_badr;
sbuf3.sb_rsiz = sbuf3.sb_bsiz / sort_krec_size;
sbuf3.sb_rcnt = 0;
one_merge_pass();
if (sort_merge_cnt != sort_rec_cnt)
sort_error("Merge Count Error");
if (sort_state != SORT_DONE)
{ sbuf1.sb_file = sbuf3.sb_file;
sbuf3.sb_file = sbuf2.sb_file;
sbuf2.sb_file = sbuf1.sb_file;
}
}
sort_merge_cnt = 0;
sort_next_fpos = 0;
sbuf1.sb_bsiz += sbuf2.sb_bsiz + sbuf3.sb_bsiz;
sbuf1.sb_rsiz = sbuf1.sb_rcnt = 0;
sbuf1.sb_radr = NULL;
lseek(sbuf1.sb_file, 0L, 0);
get_merge_block(&sbuf1);
}
static one_merge_pass()
{
char *r1, *r2, *sort_read();
long block_size;
while (sort_merge_cnt < sort_rec_cnt)
{ get_merge_block(&sbuf1);
get_merge_block(&sbuf2);
if (sbuf1.sb_fcnt >= sort_rec_cnt)
{ sort_state = SORT_DONE;
return;
}
block_size = sbuf1.sb_fcnt + sbuf2.sb_fcnt;
sort_write(sbuf3.sb_file, (char *)&block_size, sizeof(long));
r1 = sort_read(&sbuf1);
r2 = sort_read(&sbuf2);
while (r1 && r2)
{ switch (sort_cmp(r1,r2))
{ case -1: merge_write(&sbuf1);
r1 = sort_read(&sbuf1);
break;
case 0: merge_write(&sbuf1);
merge_write(&sbuf2);
r1 = sort_read(&sbuf1);
r2 = sort_read(&sbuf2);
break;
case 1: merge_write(&sbuf2);
r2 = sort_read(&sbuf2);
break;
}
}
while (r1)
{ merge_write(&sbuf1);
r1 = sort_read(&sbuf1);
}
while (r2)
{ merge_write(&sbuf2);
r2 = sort_read(&sbuf2);
}
if (sbuf3.sb_rcnt)
{ sort_write(sbuf3.sb_file, sbuf3.sb_badr, sbuf3.sb_rcnt*sort_krec_size);
sbuf3.sb_rcnt = 0;
sbuf3.sb_radr = sbuf3.sb_badr;
}
}
}
/*
* merge_init - Merge Initialization
*/
merge_init()
{
unsigned int buf_size;
if (sbuf1.sb_rcnt)
{ qsort(sbuf1.sb_badr, (int)sbuf1.sb_rcnt, sort_krec_size, sort_cmp);
sort_write(sfile2, (char *)&sbuf1.sb_rcnt, sizeof(long));
sort_write(sfile2, sbuf1.sb_badr, sbuf1.sb_rcnt*sort_krec_size);
sbuf1.sb_rcnt = 0;
sbuf1.sb_radr = sbuf1.sb_badr;
}
buf_size = sbuf1.sb_bsiz / 3;
buf_size -= buf_size % sort_krec_size;
sbuf1.sb_bsiz = buf_size;
sbuf2.sb_bsiz = buf_size;
sbuf3.sb_bsiz = buf_size;
sbuf2.sb_badr = sbuf1.sb_badr + buf_size;
sbuf3.sb_badr = sbuf2.sb_badr + buf_size;
sbuf1.sb_rsiz = sbuf1.sb_rcnt = 0;
sbuf2.sb_rsiz = sbuf2.sb_rcnt = 0;
sbuf3.sb_rsiz = sbuf3.sb_rcnt = 0;
sbuf1.sb_radr = NULL;
sbuf2.sb_radr = NULL;
sbuf3.sb_radr = NULL;
sbuf1.sb_file = sfile2;
sbuf1.sb_fcnt = 0;
sbuf1.sb_fpos = 0L;
sbuf2.sb_file = sfile2;
sbuf2.sb_fcnt = 0;
sbuf2.sb_fpos = 0L;
sbuf3.sb_file = sfile3;
sbuf3.sb_fcnt = 0;
sbuf3.sb_fpos = 0L;
}
/*
* sort_return - return a record from the sort
*/
char *sort_return(buf)
char *buf;
{
long *key;
char *sort_read();
if (sort_state == SORT_EOF)
{ sort_close();
return(NULL);
}
if (sort_state != SORT_DONE)
sort_error("Sort Return Sequence Error");
key = (long *) sort_read(&sbuf1);
if (!key)
{ sort_close();
return(NULL);
}
lseek(sfile1, (long)((*key-1)*sort_rec_size), 0);
if (read(sfile1, buf, sort_rec_size) != sort_rec_size)
sort_error("Return Read Error");
return(buf);
}
/*
* sort_read - Read record from merge buffer
*/
static char *sort_read(buf)
struct sort_buffer *buf;
{
int cnt;
if (buf->sb_rcnt < buf->sb_rsiz)
{ buf->sb_rcnt++;
buf->sb_radr += sort_krec_size;
return(buf->sb_radr);
}
if (!buf->sb_fcnt) return(NULL);
lseek(buf->sb_file, buf->sb_fpos, 0);
buf->sb_rsiz = buf->sb_bsiz / sort_krec_size;
if (buf->sb_rsiz > buf->sb_fcnt)
buf->sb_rsiz = buf->sb_fcnt;
if (read(buf->sb_file, buf->sb_badr, buf->sb_rsiz * sort_krec_size) <= 0)
sort_error("Temp File Read Error");
buf->sb_fcnt -= buf->sb_rsiz;
buf->sb_fpos += buf->sb_rsiz * sort_krec_size;
buf->sb_rcnt = 1;
buf->sb_radr = buf->sb_badr;
return(buf->sb_radr);
}
/*
* get_merge_block - Read up the next merge block
*/
get_merge_block(buf)
struct sort_buffer *buf;
{
buf->sb_rsiz = 0;
buf->sb_rcnt = 0;
buf->sb_radr = 0;
if (sort_merge_cnt >= sort_rec_cnt)
{ buf->sb_fcnt = 0;
return;
}
lseek(buf->sb_file, sort_next_fpos, 0);
if (read(buf->sb_file, &buf->sb_fcnt, sizeof(long)) <= 0)
sort_error("Merge Read Error");
buf->sb_fpos = sort_next_fpos + sizeof(long);
sort_merge_cnt += buf->sb_fcnt;
sort_next_fpos += sizeof(long) + buf->sb_fcnt * sort_krec_size;
}
/*
* merge_write - merge output
*/
static merge_write(buf)
struct sort_buffer *buf;
{
memcpy(sbuf3.sb_radr, buf->sb_radr, sort_krec_size);
sbuf3.sb_rcnt++;
if (sbuf3.sb_rcnt < sbuf3.sb_rsiz)
sbuf3.sb_radr += sort_krec_size;
else
{ sort_write(sbuf3.sb_file, sbuf3.sb_badr, sbuf3.sb_rcnt*sort_krec_size);
sbuf3.sb_rcnt = 0;
sbuf3.sb_radr = sbuf3.sb_badr;
}
}
/*
* sort_close - Cleanup after a sort
*/
static sort_close()
{
struct key_field *f, *t;
if (sort_state == SORT_CLOSED) return;
close(sfile1);
close(sfile2);
close(sfile3);
unlink("SORT1.TMP");
unlink("SORT2.TMP");
unlink("SORT3.TMP");
f = key_spec;
while (f)
{ t = f->kf_next;
free(f);
f = t;
}
free(sort_key_rec);
free(sbuf1.sb_badr);
sort_state = SORT_CLOSED;
}
/*
* sort_write - Write a reord to temp file
*/
static sort_write(fd, buf, cnt)
int fd, cnt;
char *buf;
{
if (write(fd, buf, cnt) < cnt)
sort_error("Write Error, Check Disk Space");
}
/*
* sort_error - Sort Error Exit
*/
static sort_error(text)
char *text;
{
fprintf(stderr,"\n\nSort Error: %s\7\n\n",text);
exit(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -