some fast patch
This commit is contained in:
parent
9c671b8527
commit
b38b829612
9 changed files with 150 additions and 7 deletions
|
|
@ -108,6 +108,17 @@ typedef struct global {
|
||||||
TypeDicSeg Jpeepidx;
|
TypeDicSeg Jpeepidx;
|
||||||
} Global;
|
} Global;
|
||||||
|
|
||||||
|
typedef struct dictskipseg {
|
||||||
|
u_int first;
|
||||||
|
u_short count;
|
||||||
|
TypeDicOfs end;
|
||||||
|
} DictSkipSeg;
|
||||||
|
|
||||||
|
typedef struct dictskipent {
|
||||||
|
TypeDicOfs offset;
|
||||||
|
u_short lower;
|
||||||
|
} DictSkipEnt;
|
||||||
|
|
||||||
typedef struct vfile {
|
typedef struct vfile {
|
||||||
u_char* buffer;
|
u_char* buffer;
|
||||||
u_int size;
|
u_int size;
|
||||||
|
|
@ -128,7 +139,9 @@ typedef struct dictfile {
|
||||||
long idxstrt;
|
long idxstrt;
|
||||||
long segstrt;
|
long segstrt;
|
||||||
|
|
||||||
TypeIdxOfs* ofsptr;
|
TypeIdxOfs* ofsptr;
|
||||||
|
DictSkipSeg* skipseg;
|
||||||
|
DictSkipEnt* skipent;
|
||||||
|
|
||||||
struct dictfile* link;
|
struct dictfile* link;
|
||||||
} DictFile;
|
} DictFile;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ CLREC* alloc_clrec(SJ4_CONTEXT2);
|
||||||
void free_clrec(SJ4_CONTEXT CLREC*);
|
void free_clrec(SJ4_CONTEXT CLREC*);
|
||||||
|
|
||||||
/* charsize.c */
|
/* charsize.c */
|
||||||
static __inline int codesize_inline(u_char code) {
|
static __inline int
|
||||||
|
codesize_inline(u_char code) {
|
||||||
switch(code & KANJIMODEMASK) {
|
switch(code & KANJIMODEMASK) {
|
||||||
case ZENHIRAASSYUKU:
|
case ZENHIRAASSYUKU:
|
||||||
case ZENKATAASSYUKU:
|
case ZENKATAASSYUKU:
|
||||||
|
|
@ -159,7 +160,8 @@ int getkanji(SJ4_CONTEXT u_char*, int, u_char*, u_char*);
|
||||||
void getrank(SJ4_CONTEXT2);
|
void getrank(SJ4_CONTEXT2);
|
||||||
|
|
||||||
/* hzstrlen.c */
|
/* hzstrlen.c */
|
||||||
static __inline int euc_codesize_inline(u_char c) {
|
static __inline int
|
||||||
|
euc_codesize_inline(u_char c) {
|
||||||
if((c & KANJIMODEMASK) == 0x90) {
|
if((c & KANJIMODEMASK) == 0x90) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if(isknj1(c)) {
|
} else if(isknj1(c)) {
|
||||||
|
|
@ -268,6 +270,7 @@ extern u_char kigou[];
|
||||||
/* sdepend.c */
|
/* sdepend.c */
|
||||||
DictFile* opendict(SJ4_CONTEXT char*, char*);
|
DictFile* opendict(SJ4_CONTEXT char*, char*);
|
||||||
int closedict(SJ4_CONTEXT DictFile*);
|
int closedict(SJ4_CONTEXT DictFile*);
|
||||||
|
u_char* skipdict(SJ4_CONTEXT u_char*, TypeDicSeg, u_char);
|
||||||
StdyFile* openstdy(SJ4_CONTEXT char*, char*);
|
StdyFile* openstdy(SJ4_CONTEXT char*, char*);
|
||||||
int closestdy(SJ4_CONTEXT StdyFile*);
|
int closestdy(SJ4_CONTEXT StdyFile*);
|
||||||
int putstydic(SJ4_CONTEXT2);
|
int putstydic(SJ4_CONTEXT2);
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ typedef struct dict {
|
||||||
IFunc putidx;
|
IFunc putidx;
|
||||||
IFunc putdic;
|
IFunc putdic;
|
||||||
IFunc rszdic;
|
IFunc rszdic;
|
||||||
|
VFuncDict skipdic;
|
||||||
} DICT;
|
} DICT;
|
||||||
|
|
||||||
typedef struct dictl {
|
typedef struct dictl {
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,12 @@ typedef int (*IFuncDict)(
|
||||||
#endif
|
#endif
|
||||||
void*);
|
void*);
|
||||||
|
|
||||||
|
typedef void* (*VFuncDict)(
|
||||||
|
#ifndef SJ4_GLOBAL
|
||||||
|
void*,
|
||||||
|
#endif
|
||||||
|
void*, short);
|
||||||
|
|
||||||
typedef u_char TypeGroup;
|
typedef u_char TypeGroup;
|
||||||
typedef u_char TypeGram;
|
typedef u_char TypeGram;
|
||||||
typedef u_short TypeIdxOfs;
|
typedef u_short TypeIdxOfs;
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,9 @@ void initwork(SJ4_CONTEXT2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SJ4_GLOBAL
|
#ifndef SJ4_GLOBAL
|
||||||
Sj4Context* alloccontext(const char* dic) {
|
Sj4Context*
|
||||||
Sj4Context* ctx = calloc(1, sizeof(*ctx));
|
alloccontext(const char* dic) {
|
||||||
|
Sj4Context* ctx = (Sj4Context*)calloc(1, sizeof(*ctx));
|
||||||
DictFile* dict;
|
DictFile* dict;
|
||||||
DICTL* node;
|
DICTL* node;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,114 @@ rszdic(SJ4_CONTEXT DictFile* dp, TypeDicSeg seg) {
|
||||||
return fputfile(dp->fp, 0, HEADERLENGTH, dp->buffer);
|
return fputfile(dp->fp, 0, HEADERLENGTH, dp->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
freedicskip(DictFile* dp) {
|
||||||
|
free((char*)dp->skipent);
|
||||||
|
free((char*)dp->skipseg);
|
||||||
|
dp->skipent = NULL;
|
||||||
|
dp->skipseg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mkdicskip(DictFile* dp) {
|
||||||
|
DictSkipSeg* segs;
|
||||||
|
DictSkipEnt* ents;
|
||||||
|
u_short* stack;
|
||||||
|
u_int total = 0;
|
||||||
|
int seg;
|
||||||
|
|
||||||
|
if(dp->dict.maxunit != 0 || dp->dict.segunit <= 0) return;
|
||||||
|
|
||||||
|
segs = (DictSkipSeg*)calloc(dp->dict.segunit, sizeof(*segs));
|
||||||
|
if(segs == NULL) return;
|
||||||
|
|
||||||
|
for(seg = 0; seg < dp->dict.segunit; seg++) {
|
||||||
|
u_char* base = dp->buffer + dp->segstrt + dp->dict.seglen * seg;
|
||||||
|
u_char* p = base + *base + 1;
|
||||||
|
|
||||||
|
segs[seg].first = total;
|
||||||
|
while(p < base + dp->dict.seglen && *p != DICSEGTERM) {
|
||||||
|
segs[seg].count++;
|
||||||
|
total++;
|
||||||
|
p = getntag(p);
|
||||||
|
}
|
||||||
|
segs[seg].end = (TypeDicOfs)(p - base);
|
||||||
|
}
|
||||||
|
|
||||||
|
ents = (DictSkipEnt*)malloc(total * sizeof(*ents));
|
||||||
|
stack = (u_short*)malloc(dp->dict.seglen * sizeof(*stack));
|
||||||
|
if(ents == NULL || stack == NULL) {
|
||||||
|
free((char*)stack);
|
||||||
|
free((char*)ents);
|
||||||
|
free((char*)segs);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(seg = 0; seg < dp->dict.segunit; seg++) {
|
||||||
|
DictSkipSeg* s = &segs[seg];
|
||||||
|
u_char* base = dp->buffer + dp->segstrt + dp->dict.seglen * seg;
|
||||||
|
u_char* p = base + *base + 1;
|
||||||
|
int top = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < s->count; i++) {
|
||||||
|
ents[s->first + i].offset = (TypeDicOfs)(p - base);
|
||||||
|
p = getntag(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = s->count - 1; i >= 0; i--) {
|
||||||
|
u_char plen = getplen(base + ents[s->first + i].offset);
|
||||||
|
|
||||||
|
while(top > 0 && getplen(base + ents[s->first + stack[top - 1]].offset) >= plen) top--;
|
||||||
|
|
||||||
|
ents[s->first + i].lower = (top > 0) ? stack[top - 1] : s->count;
|
||||||
|
stack[top++] = (u_short)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free((char*)stack);
|
||||||
|
dp->skipseg = segs;
|
||||||
|
dp->skipent = ents;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u_char*
|
||||||
|
skipdic(SJ4_CONTEXT u_char* tagp, TypeDicSeg seg) {
|
||||||
|
DictFile* dp = (DictFile*)curdict;
|
||||||
|
DictSkipSeg* s;
|
||||||
|
TypeDicOfs offset;
|
||||||
|
int lo, hi;
|
||||||
|
u_short i;
|
||||||
|
|
||||||
|
if(dp->skipseg == NULL || seg < 0 || seg >= dp->dict.segunit) return NULL;
|
||||||
|
|
||||||
|
s = &dp->skipseg[seg];
|
||||||
|
offset = (TypeDicOfs)(tagp - dicbuf);
|
||||||
|
lo = 0;
|
||||||
|
hi = s->count - 1;
|
||||||
|
while(lo <= hi) {
|
||||||
|
int mid = (lo + hi) / 2;
|
||||||
|
TypeDicOfs moff = dp->skipent[s->first + mid].offset;
|
||||||
|
|
||||||
|
if(moff < offset)
|
||||||
|
lo = mid + 1;
|
||||||
|
else if(moff > offset)
|
||||||
|
hi = mid - 1;
|
||||||
|
else {
|
||||||
|
i = (u_short)mid;
|
||||||
|
while(i < s->count) {
|
||||||
|
u_short next = dp->skipent[s->first + i].lower;
|
||||||
|
|
||||||
|
if(next >= s->count) return dicbuf + s->end;
|
||||||
|
i = next;
|
||||||
|
if(getplen(dicbuf + dp->skipent[s->first + i].offset) <= dicsaml)
|
||||||
|
return dicbuf + dp->skipent[s->first + i].offset;
|
||||||
|
}
|
||||||
|
return dicbuf + s->end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DictFile*
|
DictFile*
|
||||||
opendict(SJ4_CONTEXT char* name, char* passwd) {
|
opendict(SJ4_CONTEXT char* name, char* passwd) {
|
||||||
FILE* fp = NULL;
|
FILE* fp = NULL;
|
||||||
|
|
@ -298,6 +406,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
|
||||||
dfp->dict.putidx = (IFunc)putidx;
|
dfp->dict.putidx = (IFunc)putidx;
|
||||||
dfp->dict.putdic = (IFunc)putdic;
|
dfp->dict.putdic = (IFunc)putdic;
|
||||||
dfp->dict.rszdic = (IFunc)rszdic;
|
dfp->dict.rszdic = (IFunc)rszdic;
|
||||||
|
dfp->dict.skipdic = (VFuncDict)skipdic;
|
||||||
dfp->refcnt = 1;
|
dfp->refcnt = 1;
|
||||||
dfp->fp = fp;
|
dfp->fp = fp;
|
||||||
dfp->vf = vf;
|
dfp->vf = vf;
|
||||||
|
|
@ -314,6 +423,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
|
||||||
goto error3;
|
goto error3;
|
||||||
}
|
}
|
||||||
mkidxtbl(SJ4_CONTEXT_PASS & (dfp->dict));
|
mkidxtbl(SJ4_CONTEXT_PASS & (dfp->dict));
|
||||||
|
mkdicskip(dfp);
|
||||||
|
|
||||||
dfp->link = dictlink;
|
dfp->link = dictlink;
|
||||||
dictlink = dfp;
|
dictlink = dfp;
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,15 @@ srchdict(SJ4_CONTEXT u_char* tagp) {
|
||||||
return tagp;
|
return tagp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(cmp == CONT && getnlen(tagp) != 0 && getplen(tagp) > dicsaml && curdict->skipdic != NULL) {
|
||||||
|
u_char* next = (*curdict->skipdic)(SJ4_CONTEXT_PASS tagp, segno);
|
||||||
|
|
||||||
|
if(next != NULL) {
|
||||||
|
tagp = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
tagp = getntag(tagp);
|
tagp = getntag(tagp);
|
||||||
}
|
}
|
||||||
dicinl = dicsaml + 1;
|
dicinl = dicsaml + 1;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ static struct sj4table {
|
||||||
Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet) {
|
Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet) {
|
||||||
Sj4Ime* ime;
|
Sj4Ime* ime;
|
||||||
|
|
||||||
if((ime = calloc(1, sizeof(*ime))) == NULL) return NULL;
|
if((ime = (Sj4Ime*)calloc(1, sizeof(*ime))) == NULL) return NULL;
|
||||||
|
|
||||||
if((ime->lib = sj4_open(charset, dict)) == NULL) {
|
if((ime->lib = sj4_open(charset, dict)) == NULL) {
|
||||||
free((char*)ime);
|
free((char*)ime);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ Sj4Lib* sj4_open(int charset, const char* dic) {
|
||||||
if(charset == SJ4UTF8 || charset == SJ4UTF16) return NULL;
|
if(charset == SJ4UTF8 || charset == SJ4UTF16) return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if((ctx = calloc(1, sizeof(*ctx))) == NULL) return NULL;
|
if((ctx = (Sj4Lib*)calloc(1, sizeof(*ctx))) == NULL) return NULL;
|
||||||
|
|
||||||
if((ctx->ctx = alloccontext(dic)) == NULL) {
|
if((ctx->ctx = alloccontext(dic)) == NULL) {
|
||||||
free((char*)ctx);
|
free((char*)ctx);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue