Namazu-devel-ja(旧)


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

日付順ソートに関して



寺西です。

現在、検索結果の日付ソートはファイルのタイムスタンプを元に行って
います。mailutime を使えば、ファイルのタイムスタンプを本文中の日付
情報に変更することができますが、手間がかかります。また、mailutime 
忘れの場合、結果で表示される日付と、ソートにもちいる日付が異なるため
利用者の期待した結果にはソートされません。

そのため、--sort=date の際に、フィールドの date を用いてソートする
ように stable-2-0 用のパッチを作成しました。

パッチの内容:
・mailnews.pl を修正し、mhonarc.pl 同様 ヘッダの Date 情報を
  フィールド date に反映するようにしました。
・--sort=date の場合、フィールドの date 情報を元にソーティング
  するようにしました。
  (フィールドの date 情報がない場合等は、従来通りファイルのタイム
  スタンプを用います。)
・--sort=field:date の場合、--sort=date と同じ動作をするように
  しました。(文字列や数値とは別に、日付として認識)
・注意) timezone は考慮していません。timezone の異なるファイルが
 混在した場合は正しく処理できません。
・mailutime を使う必要がなくなったと思います。

動作確認およびご意見をお聞かせいただけると助かります。
=====================================================================
NMZ.t の中身自体を変更しようかと思いましたが、インデックスファイル
の更新処理に影響がでるので、これはやめました。

このため、現在の --sort=date よりは、処理が増える分、速度が落ちる
かもしれません。(それほど気にすることはないと思いますが。)
-- 
=====================================================================
寺西 忠勝(TADAMASA TERANISHI)  yw3t-trns@xxxxxxxxxxxxxxx
http://www.asahi-net.or.jp/~yw3t-trns/index.htm
Key fingerprint =  474E 4D93 8E97 11F6 662D  8A42 17F5 52F4 10E7 D14E
*** namazu/nmz/hlist.c	Sun Jun  8 22:50:37 2003
--- namazu-new/nmz/hlist.c	Sun Jun 15 18:45:22 2003
***************
*** 29,34 ****
--- 29,35 ----
  #include <stdio.h>
  #include <stdlib.h>
  #include <math.h>
+ #include <time.h>
  #include <errno.h>
  #ifdef HAVE_CONFIG_H
  #  include "config.h"
***************
*** 62,67 ****
--- 63,72 ----
  #include "score.h"
  static int document_number = 0;  /* Number of documents covered in a target index */
  static char field_for_sort[BUFSIZE] = "";  /* field_for_sort name used with sorting */
+ static char *months[] = {
+     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ };
  
  /*
   *
***************
*** 74,82 ****
--- 79,89 ----
  static int  field_sort(NmzResult);
  static int  field_scmp(const void*, const void*);
  static int  field_ncmp(const void*, const void*);
+ static int  field_dcmp(const void*, const void*);
  static int  date_cmp(const void*, const void*);
  static int  score_cmp(const void*, const void*);
  static int  intcmp(int v1, int v2);
+ static time_t  get_time_from_rfc822time(const char*);
  
  static void 
  memcpy_hlist(NmzResult to, NmzResult from, int n)
***************
*** 125,131 ****
  	strcpy(hlist.data[i].field, buf);
      } 
  
!     if (numeric == 1) {
  	qsort(hlist.data, hlist.num, sizeof(hlist.data[0]), field_ncmp);
  	
      } else {
--- 132,141 ----
  	strcpy(hlist.data[i].field, buf);
      } 
  
!     if (!strcmp("date", field_for_sort)) {
! 	qsort(hlist.data, hlist.num, sizeof(hlist.data[0]), field_dcmp);
!     }
!     else if (numeric == 1) {
  	qsort(hlist.data, hlist.num, sizeof(hlist.data[0]), field_ncmp);
  	
      } else {
***************
*** 170,176 ****
      v2 = (struct nmz_data *) p2;
  
      r = intcmp(atoi(v2->field), atoi(v1->field));
!     if (r ==0) {
  	r = intcmp(v2->rank, v1->rank);
      }
      return r;
--- 180,215 ----
      v2 = (struct nmz_data *) p2;
  
      r = intcmp(atoi(v2->field), atoi(v1->field));
!     if (r == 0) {
! 	r = intcmp(v2->rank, v1->rank);
!     }
!     return r;
! }
! 
! /* 
!  * Compare a pair of hlist.data[].field as string in descending order.
!  */
! static int 
! field_dcmp(const void *p1, const void *p2)
! {
!     struct nmz_data *v1, *v2;
!     int date1, date2;
!     int r;
! 
!     v1 = (struct nmz_data *) p1;
!     v2 = (struct nmz_data *) p2;
! 
!     date1 = (int)get_time_from_rfc822time(v1->field);
!     if (date1 == -1) {
!         date1 = v1->date;
!     }
!     date2 = (int)get_time_from_rfc822time(v2->field);
!     if (date2 == -1) {
!         date2 = v2->date;
!     }
! 
!     r = intcmp(date2, date1);
!     if (r == 0) {
  	r = intcmp(v2->rank, v1->rank);
      }
      return r;
***************
*** 615,621 ****
--- 654,666 ----
  	if (field_sort(hlist) != SUCCESS)
  	    return FAILURE;
      } else if (method == SORT_BY_DATE) {
+ #if 0
  	qsort(hlist.data, hlist.num, sizeof(hlist.data[0]), date_cmp);
+ #else
+         nmz_set_sortfield("date");
+ 	if (field_sort(hlist) != SUCCESS)
+ 	    return FAILURE;
+ #endif
      } else if (method == SORT_BY_SCORE) {
  	qsort(hlist.data, hlist.num, sizeof(hlist.data[0]), score_cmp);
      } 
***************
*** 671,674 ****
--- 716,761 ----
  nmz_get_docnum()
  {
      return document_number;
+ }
+ 
+ static time_t get_time_from_rfc822time(const char *str_time)
+ {
+     int i;
+     int mday, mon, year, hour, minute, sec;
+     char str_mon[64];
+     struct tm time;
+ 
+     sscanf(str_time, "%*3s, %d %s %d %d:%d:%d",
+         &mday, str_mon, &year, &hour, &minute, &sec);
+ 
+     mon = 0;
+     for(i = 0; i < 12; i++) {
+         if (!strcmp(months[i], str_mon)) {
+             mon = i + 1;
+             break;
+         }
+     }
+ 
+     if (mon == 0) {
+         return (time_t)-1;
+     }
+ 
+     if (year < 50) {
+         year += 2000;
+     }
+     else if (year >= 50 && year <= 99) {
+         year += 1900;
+     }
+ 
+     time.tm_sec = sec;          /* [0 - 59] */
+     time.tm_min = minute;       /* [0 - 59] */
+     time.tm_hour = hour;        /* [0 - 23] */
+     time.tm_mday = mday;
+     time.tm_mon = mon - 1;      /* [0 - 11] */
+     time.tm_year = year - 1900; /* since 1900. */
+     time.tm_wday = 0;
+     time.tm_yday = 0;
+     time.tm_isdst = 0;
+ 
+     return mktime(&time);
  }
*** namazu/filter/mailnews.pl	Mon Apr 23 18:09:38 2001
--- namazu-new/filter/mailnews.pl	Sun Jun 15 18:09:41 2003
***************
*** 111,117 ****
  
  	    my $weight = $conf::Weight{'html'}->{'title'};
  	    $$weighted_str .= "\x7f$weight\x7f$line\x7f/$weight\x7f\n";
!  	} elsif ($line =~ s/^content-type:\s*//i) {
  	    if ($line =~ /multipart.*boundary="(.*)"/i){
  		$boundary = $1;
  		util::dprint("((boundary: $boundary))\n");
--- 111,117 ----
  
  	    my $weight = $conf::Weight{'html'}->{'title'};
  	    $$weighted_str .= "\x7f$weight\x7f$line\x7f/$weight\x7f\n";
!         } elsif ($line =~ s/^content-type:\s*//i) {
  	    if ($line =~ /multipart.*boundary="(.*)"/i){
  		$boundary = $1;
  		util::dprint("((boundary: $boundary))\n");
***************
*** 124,129 ****
--- 124,132 ----
  	} elsif ($line =~ /^(\S+):\s*(.*)/i) {
  	    my $name = $1;
  	    my $value = $2;
+             if ($name =~ /Date/i) {
+                 $fields->{'date'} = $value;
+             }
  	    $fields->{lc($name)} = $value;
  	    if ($name =~ /^($conf::REMAIN_HEADER)$/io) {
  		# keep some fields specified REMAIN_HEADER for search keyword