Namazu-devel-ja(旧)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
BER圧縮のデータの読み込みについて
- From: "Hideyuki Takahashi" <k176@xxxxxxxxxx>
- Date: Tue, 2 Dec 2003 23:22:35 +0900 (JST)
- X-ml-name: namazu-devel-ja
- X-mail-count: 03385
はじめまして、図書館情報大学4年の高橋というものです。
Namazuを焼こうと、下ごしらえをいろいろとやっています。
さて、 MLのusers-jaの03312、フレーズ検索のHASH値への変換方法の
スレッドで話題になった件で気になった点をあげます。
こちらのバグに気づき、藤原さんが書かれた最新版(13pre7)の
ソースを拝見したのですが、まだうまくいってないと思います。
参考のため、関数を載せさせていただきます。
まず、nmz_get_unpckw()で、NMZ.iの対象語の一つ目のデータ
(表記について問題になったもの)をnに代入していますが、
この時点のnは、データ長、つまりバイトですよね。
それをmaxhit * 2と比較するのはおかしいかと思います。
具体的に、駄目な例ですが、文書IDが128、スコアが128の場合、
これ一つだけだと、nは4(byte)が入りますね。
これが500個あるとすると、
(差分を考慮すると、文書IDは2個目だったら実IDは256、という意味です)
n = 4(byte) * 500 = 2000(byte) になります。
しかし、実際のデータの数は500ですので、
hit = (bersize < maxhit * 2 ? bersize : maxhit * 2);
の式は、hitに maxhit * 2 がはいってしまします。
(maxhit ってデフォルトで1000ですよね?)
よって、この式を評価する前に、nに文書数を入れておく必要があります。
というか、nが場所によって、バイト数になったり、ヒット文書数*2になったり
ヒット文書数になったりしているので、別な変数を用意したほうが
よいのではないかと思います。
これが1点。
もうひとつが、
idf = log((double)document_number / (n/2)) / log(2);
nmz_debug_printf("idf: %f (N:%d, n:%d)\n", idf, document_number, n/2);
ここでのnは、やはりバイト数が入っているままなのですが、これだと
やはりいけないと思います。
ここで用いたい「n」は「ヒット文書数 * 2」なので。
それで、上記の解決策ですが、nmz_get_unpackw()で
バイト数を求めた後、直後に、buf = malloc(n * sizeof(int));
をすれば大丈夫だと思います。
しかし!!余分にメモリを確保する(可能性がある)のはいなめないのですが。。。
皆様のご意見をお待ちしております。
長文になって申し訳ございません。
P.S.
「BER圧縮」ってベル圧縮と読んでいいのでしょうか?
図書館情報大学4年
高橋英幸 <k176@xxxxxxxxxx>
NmzResult
nmz_get_hlist(int index)
{
int n, *buf, i;
NmzResult hlist;
double idf = 1.0;
hlist.num = 0;
hlist.data = NULL;
hlist.stat = SUCCESS;
if (-1 == fseek(Nmz.i, nmz_getidxptr(Nmz.ii, index), 0)) {
hlist.stat = ERR_FATAL;
return hlist; /* error */
}
nmz_get_unpackw(Nmz.i, &n);
if (nmz_is_tfidfmode() &&
(nmz_get_querytokennum() > 1
/* 0th token is a phrase. */
|| strchr(nmz_get_querytoken(0), '\t') != NULL))
{
idf = log((double)document_number / (n/2)) / log(2);
nmz_debug_printf("idf: %f (N:%d, n:%d)\n", idf, document_number, n/2);
}
{
int sum = 0;
int hit;
int maxhit = nmz_get_maxhit();
int bersize = n;
int totalsize;
hit = (bersize < maxhit * 2 ? bersize : maxhit * 2);
buf = malloc(hit * sizeof(int));
if (buf == NULL) {
nmz_set_dyingmsg(nmz_msg("%s", strerror(errno)));
hlist.data = NULL;
hlist.stat = ERR_FATAL;
return hlist;
}
n = 0;
totalsize = 0;
while (totalsize < bersize) {
totalsize += nmz_get_unpackw(Nmz.i, &buf[n]);
n++;
if (n > maxhit * 2) {
hlist.stat = ERR_TOO_MUCH_HIT;
free(buf);
return hlist;
}
}
n /= 2;
nmz_malloc_hlist(&hlist, n);
if (hlist.stat == ERR_FATAL) {
free(buf);
return hlist;
}
for (i = 0; i < n; i++) {
hlist.data[i].docid = *(buf + i * 2) + sum;
sum = hlist.data[i].docid;
hlist.data[i].score = *(buf + i * 2 + 1);
if (nmz_is_tfidfmode()) {
hlist.data[i].score = (int)(hlist.data[i].score * idf) + 1;
}
}
hlist.num = n;
free(buf);
hlist = nmz_do_date_processing(hlist);
}
return hlist;
}