namazu-dev(ring)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
internal/suffix match
- From: Rei FURUKAWA <furukawa@xxxxxxxxxxxxxxxx>
- Date: Fri, 17 Sep 1999 12:40:26 +0900 (JST)
古川です。
日本語の中間一致、後方一致を正規表現検索として扱うときに、NMZ.w を日本
語の先頭まで seek しておいたほうが、速くなるはず、と思います。
具体的には、'*' の後の文字の最上位ビットが立っていたら、NMZ.w を、「先
頭の文字の最上位ビットが立っている行」まで seek します。(新形式では、
NMZ.wi があるので、それが可能になっています)
ただ、ちょっと迷うところがありまして…
(1) seek 位置をいつ計算するか。
下のコードでは、検索時に計算しています。これを、あらかじめ mknmz で計算
しておいて、ファイルに記録しておけば、もう少し速くなるかもしれません。
ただ、どのファイルに記録するか…(または、これだけのために新しくファイル
を作るか?)
(2) 世界進出との兼ね合い
この話は、ASCII と EUC-JP が、必ず別の単語に分かれることが前堤になって
います。Latin などでは、ASCII と共に一つの単語を構成することがあるので、
適用できません。何らかの方法で、seek する/しないを切り換える必要があり
そうです。そういった意味では、(1) は mknmz で行なうようにして、ついでに
日本語かどうか判断するようにしたほうがいいかも。
というわけで、直ちに commit はせず、patch を付けておくことにします。
--
ヤマハ(株)ピアノプレーヤ設計課
古川 令
furukawa@xxxxxxxxxxxxxxxx
--- re.c.orig Mon Sep 13 13:32:21 1999
+++ re.c Fri Sep 17 02:32:24 1999
@@ -142,11 +142,11 @@
return 0;
}
-HLIST regex_grep(uchar *orig_expr, FILE *fp, uchar *field, int field_mode)
+HLIST regex_grep(uchar *orig_expr, FILE *fp, uchar *field, int field_mode, int i)
{
unsigned char buf[BUFSIZE], expr[BUFSIZE];
REGEX *rp;
- int i, n, size = 0, max, uri_mode = 0;
+ int n, size = 0, max, uri_mode = 0;
HLIST val, tmp;
val.n = 0;
@@ -180,7 +180,7 @@
re_compile_pattern(expr, strlen(expr), rp);
- for (i = n = 0; fgets(buf, BUFSIZE, fp); i++) {
+ for (n = 0; fgets(buf, BUFSIZE, fp); i++) {
if (*(lastc(buf)) != '\n') { /* too long */
i--;
continue;
--- re.h.orig Mon Sep 13 13:32:21 1999
+++ re.h Fri Sep 17 02:30:52 1999
@@ -6,6 +6,6 @@
#define MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))
int replace_uri(uchar*);
-HLIST regex_grep(uchar*, FILE*, uchar*, int);
+HLIST regex_grep(uchar*, FILE*, uchar*, int, int);
#endif /* _RE_H */
--- search.c.orig Thu Sep 16 23:49:48 1999
+++ search.c Fri Sep 17 02:54:22 1999
@@ -68,7 +68,7 @@
HLIST cmp_phrase_hash(int, HLIST, FILE *, FILE *);
int open_phrase_index_files(FILE**, FILE**);
HLIST do_phrase_search(uchar*, HLIST);
-void do_regex_preprocessing(uchar*);
+int do_regex_preprocessing(uchar*);
HLIST do_regex_search(uchar*, HLIST);
void get_expr(uchar*, uchar*);
HLIST do_field_search(uchar*, HLIST);
@@ -444,26 +444,27 @@
}
#define iseuc(c) ((c) >= 0xa1 && (c) <= 0xfe)
-void do_regex_preprocessing(uchar *expr)
+int do_regex_preprocessing(uchar *expr)
{
- if (*expr == '*' && *(lastc(expr)) != '*') {
+ if (*expr == '*') {
+ int ret = (0x80 & *strcpy(expr, expr + 1));
+ if (*(lastc(expr)) == '*') {
+ /* if internal match such as '*foo*', enforce it into regex */
+ *(lastc(expr)) = '\0';
+ } else {
/* if suffix match such as '*bar', enforce it into regex */
- strcpy(expr, expr + 1);
strcat(expr, "$");
+ }
+ return ret;
} else if (*expr != '*' && *(lastc(expr)) == '*') {
/* if prefix match such as 'bar*', enforce it into regex */
*(lastc(expr)) = '.';
strcat(expr, "*");
- } else if (*expr == '*' && *(lastc(expr)) == '*') {
- /* if internal match such as '*foo*', enforce it into regex */
- strcpy(expr, expr + 1);
- *(lastc(expr)) = '\0';
} else if (*expr == '/' && *(lastc(expr)) == '/') {
/* genuine regex */
/* remove the both of '/' chars at begging and end of string */
strcpy(expr, expr + 1);
*(lastc(expr))= '\0';
- return;
} else {
uchar buf[BUFSIZE * 2], *bufp, *exprp;
@@ -488,15 +489,17 @@
*bufp = '\0';
strcpy(expr, buf);
}
+ return 0;
}
HLIST do_regex_search(uchar *orig_expr, HLIST val)
{
+ int offset;
FILE *fp;
uchar expr[BUFSIZE * 2]; /* because of escaping meta characters */
strcpy(expr, orig_expr);
- do_regex_preprocessing(expr);
+ offset = do_regex_preprocessing(expr);
fp = fopen(NMZ.w, "rb");
if (fp == NULL) {
@@ -504,7 +507,26 @@
val.n = ERR_REGEX_SEARCH_FAILED; /* cannot open regex index */
return val;
}
- val = regex_grep(expr, fp, "", 0);
+ if (offset) {
+ FILE *fwi = fopen(NMZ.wi, "rb");
+ offset = 0;
+ if (fwi) {
+ int l, x;
+ lrget(0, &l, &offset);
+ while (l < offset) {
+ x = (l + offset) / 2;
+ fseek(fp, getidxptr(fwi, x), 0L);
+ if (fgetc(fp) & 0x80){
+ offset = x;
+ } else {
+ l = x + 1;
+ }
+ }
+ fseek(fp, getidxptr(fwi, offset), 0);
+ fclose(fwi);
+ }
+ }
+ val = regex_grep(expr, fp, "", 0, offset);
fclose(fp);
return val;
@@ -535,7 +557,7 @@
val.n = -4; /* cannot open field index */
return val;
}
- val = regex_grep(expr, fp, field_name, 1); /* last argument must be 1 */
+ val = regex_grep(expr, fp, field_name, 1, 0); /* 4th argument must be 1 */
fclose(fp);
return val;
}