summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
Diffstat (limited to 'mbbsd')
-rw-r--r--mbbsd/read.c105
-rw-r--r--mbbsd/record.c12
2 files changed, 74 insertions, 43 deletions
diff --git a/mbbsd/read.c b/mbbsd/read.c
index d5ece956..08eac9af 100644
--- a/mbbsd/read.c
+++ b/mbbsd/read.c
@@ -433,17 +433,21 @@ select_read(const keeploc_t * locmem, int sr_mode)
time4_t filetime;
fileheader_t fhs[READSIZE];
char newdirect[MAXPATHLEN];
- char keyword[TTLEN + 1] = "";
+ int first_select;
char genbuf[MAXPATHLEN], *p = strstr(currdirect, "SR.");
static int _mode = 0;
- int len, fd, fr, i, count=0, reference = 0, n_recommend = 0,
- n_money=0, diff;
- fileheader_t *fh;
+ int reload, inc;
+ int len, fd, fr, i, count = 0, reference = 0;
+ int filemode;
+ /* selection condition */
+ char keyword[TTLEN + 1] = "";
+ int n_recommend = 0, n_money = 0;
+
if(locmem->crs_ln == 0)
return locmem->crs_ln;
- fh = &headers[locmem->crs_ln - locmem->top_ln];
+ first_select = p==NULL;
STATINC(STAT_SELECTREAD);
if(sr_mode & RS_AUTHOR)
@@ -490,22 +494,24 @@ select_read(const keeploc_t * locmem, int sr_mode)
return READ_REDRAW;
strcat(keyword, "M");
}
- else
- {
- if(p && _mode & sr_mode & (RS_TITLE | RS_NEWPOST | RS_MARK))
- return DONOTHING;
- // Ptt: only once for these modes.
- if(sr_mode & RS_TITLE)
- strcpy(keyword, subject(fh->title));
- }
+ else {
+ // Ptt: only once for these modes.
+ if(!first_select && _mode & sr_mode & (RS_TITLE | RS_NEWPOST | RS_MARK))
+ return DONOTHING;
+
+ if(sr_mode & RS_TITLE) {
+ fileheader_t *fh = &headers[locmem->crs_ln - locmem->top_ln];
+ strcpy(keyword, subject(fh->title));
+ }
+ }
- if(p == NULL)
+ if(first_select)
_mode = sr_mode;
else
_mode |= sr_mode;
snprintf(genbuf, sizeof(genbuf), "%s%X.%X.%X",
- p ? p : "SR.",
+ first_select ? "SR.":p,
sr_mode, (int)strlen(keyword), StringHash(keyword));
if( strlen(genbuf) > MAXPATHLEN - 50 )
return READ_REDRAW; // avoid overflow
@@ -518,31 +524,51 @@ select_read(const keeploc_t * locmem, int sr_mode)
filetime = dasht(newdirect);
count = dashs(newdirect) / sizeof(fileheader_t);
- diff = now - filetime;
- if( diff > 180)
- {
- if( diff > 3600)
- {
- len = O_CREAT | O_RDWR;
- count=0;
- }
- else
- len = O_APPEND | O_RDWR;
-
- if( (fd = open(newdirect, len, 0600)) == -1 )
- return READ_REDRAW;
+ if(filetime<0 || now-filetime>60*60) {
+ reload = 1;
+ inc = 0;
+ } else if(now-filetime > 3*60) {
+ reload = 1;
+ inc = 1;
+ } else {
+ /* use cached data */
+ reload = 0;
+ }
+ /* mark and recommend shouldn't incremental select */
+ if(sr_mode & (RS_MARK | RS_RECOMMEND))
+ inc = 0;
+
+ if(reload) {
if( (fr = open(currdirect, O_RDONLY, 0)) != -1 ) {
- if( diff <= 3600)
- {
- sprintf(fhs[0].filename, "X.%d", (int)filetime);
- len = - getindex(currdirect, &fhs[0], 0);
- if(len>0)
- {
- lseek(fr, len*sizeof(fileheader_t), SEEK_SET);
- reference = len;
- }
- }
+ if(inc) {
+ /* find incremental selection start point */
+ int idx;
+ sprintf(fhs[0].filename, "X.%d", (int)filetime);
+ idx = getindex(currdirect, &fhs[0], 0);
+ if(idx<0) {
+ reference = -idx;
+ } else if(idx==0) {
+ inc = 0;
+ } else {
+ reference = idx;
+ }
+ }
+ if(inc) {
+ filemode = O_APPEND | O_RDWR;
+ } else {
+ filemode = O_CREAT | O_RDWR;
+ count = 0;
+ reference = 0;
+ }
+
+ if( (fd = open(newdirect, filemode, 0600)) == -1 ) {
+ close(fr);
+ return READ_REDRAW;
+ }
+
+ if(reference>0)
+ lseek(fr, reference*sizeof(fileheader_t), SEEK_SET);
#ifdef DEBUG
vmsgf("search: %s", currdirect);
@@ -577,8 +603,7 @@ select_read(const keeploc_t * locmem, int sr_mode)
query_file_money(fhs+i) < n_money)
continue;
- if(p == NULL)
- {
+ if(first_select) {
fhs[i].multi.refer.flag = 1;
fhs[i].multi.refer.ref = reference;
}
diff --git a/mbbsd/record.c b/mbbsd/record.c
index b7ed123b..987b3e3d 100644
--- a/mbbsd/record.c
+++ b/mbbsd/record.c
@@ -67,7 +67,7 @@ get_record_keep(const char *fpath, void *rptr, int size, int id, int *fd)
/* 和 get_record() 一樣. 不過藉由 *fd, 可使同一個檔案不要一直重複開關 */
if (id >= 1 &&
(*fd > 0 ||
- ((*fd = open(fpath, O_RDONLY, 0)) > 0))){
+ ((*fd = open(fpath, O_RDONLY, 0)) > 0))){ // FIXME leak if *fd==0
if (lseek(*fd, (off_t) (size * (id - 1)), SEEK_SET) != -1) {
if (read(*fd, rptr, size) == size) {
return 0;
@@ -160,14 +160,20 @@ substitute_ref_record(const char *direct, fileheader_t * fhdr, int ent)
return num;
}
+/* return index>0 if thisstamp==stamp[index],
+ * return -index<0 if stamp[index-1]<thisstamp<stamp[index+1], XXX thisstamp ?<>? stamp[index]
+ * or XXX filename[index]=""
+ * return 0 if error
+ */
int
getindex(const char *direct, fileheader_t *fhdr, int end)
{ // Ptt: 從前面找很費力 太暴力
int fd = -1, begin = 1, i, s, times, stamp;
fileheader_t fh;
- if( end > (i = get_num_records(direct, sizeof(fileheader_t))) || end<=0 )
- end = i;
+ int n = get_num_records(direct, sizeof(fileheader_t));
+ if( end > n || end<=0 )
+ end = n;
stamp = atoi(fhdr->filename + 2);
for( i = (begin + end ) / 2, times = 0 ;
end >= begin && times < 20 ; /* 最多只找 20 次 */