some fast patch

This commit is contained in:
Nishi 2026-09-23 19:46:54 +09:00
commit b38b829612
9 changed files with 150 additions and 7 deletions

View file

@ -108,6 +108,17 @@ typedef struct global {
TypeDicSeg Jpeepidx;
} 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 {
u_char* buffer;
u_int size;
@ -129,6 +140,8 @@ typedef struct dictfile {
long segstrt;
TypeIdxOfs* ofsptr;
DictSkipSeg* skipseg;
DictSkipEnt* skipent;
struct dictfile* link;
} DictFile;

View file

@ -65,7 +65,8 @@ CLREC* alloc_clrec(SJ4_CONTEXT2);
void free_clrec(SJ4_CONTEXT CLREC*);
/* charsize.c */
static __inline int codesize_inline(u_char code) {
static __inline int
codesize_inline(u_char code) {
switch(code & KANJIMODEMASK) {
case ZENHIRAASSYUKU:
case ZENKATAASSYUKU:
@ -159,7 +160,8 @@ int getkanji(SJ4_CONTEXT u_char*, int, u_char*, u_char*);
void getrank(SJ4_CONTEXT2);
/* hzstrlen.c */
static __inline int euc_codesize_inline(u_char c) {
static __inline int
euc_codesize_inline(u_char c) {
if((c & KANJIMODEMASK) == 0x90) {
return 1;
} else if(isknj1(c)) {
@ -268,6 +270,7 @@ extern u_char kigou[];
/* sdepend.c */
DictFile* opendict(SJ4_CONTEXT char*, char*);
int closedict(SJ4_CONTEXT DictFile*);
u_char* skipdict(SJ4_CONTEXT u_char*, TypeDicSeg, u_char);
StdyFile* openstdy(SJ4_CONTEXT char*, char*);
int closestdy(SJ4_CONTEXT StdyFile*);
int putstydic(SJ4_CONTEXT2);

View file

@ -142,6 +142,7 @@ typedef struct dict {
IFunc putidx;
IFunc putdic;
IFunc rszdic;
VFuncDict skipdic;
} DICT;
typedef struct dictl {

View file

@ -55,6 +55,12 @@ typedef int (*IFuncDict)(
#endif
void*);
typedef void* (*VFuncDict)(
#ifndef SJ4_GLOBAL
void*,
#endif
void*, short);
typedef u_char TypeGroup;
typedef u_char TypeGram;
typedef u_short TypeIdxOfs;

View file

@ -74,8 +74,9 @@ void initwork(SJ4_CONTEXT2) {
}
#ifndef SJ4_GLOBAL
Sj4Context* alloccontext(const char* dic) {
Sj4Context* ctx = calloc(1, sizeof(*ctx));
Sj4Context*
alloccontext(const char* dic) {
Sj4Context* ctx = (Sj4Context*)calloc(1, sizeof(*ctx));
DictFile* dict;
DICTL* node;

View file

@ -217,6 +217,114 @@ rszdic(SJ4_CONTEXT DictFile* dp, TypeDicSeg seg) {
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*
opendict(SJ4_CONTEXT char* name, char* passwd) {
FILE* fp = NULL;
@ -298,6 +406,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
dfp->dict.putidx = (IFunc)putidx;
dfp->dict.putdic = (IFunc)putdic;
dfp->dict.rszdic = (IFunc)rszdic;
dfp->dict.skipdic = (VFuncDict)skipdic;
dfp->refcnt = 1;
dfp->fp = fp;
dfp->vf = vf;
@ -314,6 +423,7 @@ opendict(SJ4_CONTEXT char* name, char* passwd) {
goto error3;
}
mkidxtbl(SJ4_CONTEXT_PASS & (dfp->dict));
mkdicskip(dfp);
dfp->link = dictlink;
dictlink = dfp;

View file

@ -222,6 +222,15 @@ srchdict(SJ4_CONTEXT u_char* 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);
}
dicinl = dicsaml + 1;

View file

@ -39,7 +39,7 @@ static struct sj4table {
Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet) {
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) {
free((char*)ime);

View file

@ -25,7 +25,7 @@ Sj4Lib* sj4_open(int charset, const char* dic) {
if(charset == SJ4UTF8 || charset == SJ4UTF16) return NULL;
#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) {
free((char*)ctx);