|
|
researchv8 Dan Cross
/* @(#)spellin.c 1.1 */
#include <stdio.h>
#include "hash.h"
#define S (BYTE*sizeof(long))
#define B (BYTE*sizeof(unsigned))
unsigned tabword;
unsigned short index[NI];
unsigned wp; /* word pointer*/
int bp =B; /* bit pointer*/
int extra;
/* usage: hashin N
where N is number of words in dictionary
and standard input contains sorted, unique
hashed words in octal
*/
main(argc,argv)
char **argv;
{
long h,k,d;
register i;
long count;
long w;
long x;
int t,u;
extern double huff();
extern long ftell();
long seekpt;
double atof();
double z;
double nwords;
k = 0;
u = 0;
if(argc!=2) {
fprintf(stderr,"spellin: arg count\n");
exit(1);
}
nwords = atof(argv[1]);
z = huff((1L<<HASHWIDTH)/nwords);
fprintf(stderr, "spellin: expected code widths = %f", z);
z += sizeof(tabword)*BYTE/2*(double)(1<<INDEXWIDTH)/nwords;
fprintf(stderr, " +breakage = %f\n", z); /*t half word per bin */
whuff();
seekpt = ftell(stdout);
fwrite((char*)index, sizeof(*index), NI, stdout); /*dummy data */
for(count=0; scanf("%lo", &h) == 1; ++count) {
if((t=h>>(HASHWIDTH-INDEXWIDTH)) != u) {
if(bp!=B)
newword();
bp = B;
while(u<t)
index[++u] = wp;
k = (long)t<<(HASHWIDTH-INDEXWIDTH);
}
d = h-k;
k = h;
for(;;) {
for(x=d;;x/=2) {
i = encode(x,&w);
if(i>0)
break;
}
if(i>B) {
append((unsigned)(w>>(i-B)), B);
append((unsigned)(w<<(B+B-i)), i-B);
} else
append((unsigned)(w<<(B-i)), i);
d -= x;
if(d>0)
extra++;
else
break;
}
}
if(bp!=B)
newword();
while(++u<NI)
index[u] = wp;
newword(); /* padding allows one out-of-bounds fetch */
newword();
newword();
fseek(stdout, seekpt, 0); /* overwrite dummy data */
fwrite((char*)index, sizeof(*index), NI, stdout);
fprintf(stderr, "spellin: %ld items, %d extra, %u words occupied\n",
count,extra,wp);
fprintf(stderr, "spellin: %f table bits/item, ",
((float)BYTE*wp)*sizeof(tabword)/count);
fprintf(stderr, "%f table+index bits\n",
BYTE*((float)wp*sizeof(tabword) + sizeof(index))/count);
return(0);
}
append(w, i)
register unsigned w;
register i;
{
for(;;) {
tabword |= w>>(B-bp);
i -= bp;
if(i<0) {
bp = -i;
return;
}
w <<= bp;
bp = B;
newword();
}
}
newword()
{
fwrite((char*)&tabword, sizeof(tabword), 1, stdout);
wp++;
tabword = 0;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.