Commit 2573eaf7 authored by Richard P. Curnow's avatar Richard P. Curnow

Preparatory work for fast-index option

Do the stat() on each maildir and MH message late, during
and after the pass where the current on-disc paths are reconciled with the
paths already known in the database.  Previously the stat() was done when the
list of current on-disc paths was being built up.
parent 0f2c537a
......@@ -838,6 +838,22 @@ static void add_msg_path(struct database *db, char *path, time_t mtime, size_t m
++db->n_msgs;
}
/*}}}*/
static int do_stat(struct msgpath *mp)/*{{{*/
{
struct stat sb;
int status;
status = stat(mp->src.mpf.path, &sb);
if ((status < 0) ||
!S_ISREG(sb.st_mode)) {
return 0;
} else {
mp->src.mpf.mtime = sb.st_mtime;
mp->src.mpf.size = sb.st_size;
return 1;
}
}
/*}}}*/
int update_database(struct database *db, struct msgpath *sorted_paths, int n_msgs)/*{{{*/
{
/* The incoming list must be sorted into order, to make binary searching
......@@ -853,6 +869,7 @@ int update_database(struct database *db, struct msgpath *sorted_paths, int n_msg
int matched_index;
int i, new_entries_start_at;
int any_new, n_newly_pruned, n_already_dead;
int status;
file_in_db = new_array(char, n_msgs);
file_in_new_list = new_array(char, db->n_msgs);
......@@ -866,11 +883,20 @@ int update_database(struct database *db, struct msgpath *sorted_paths, int n_msg
switch (db->type[i]) {
case MTY_FILE:
matched_index = lookup_msgpath(sorted_paths, n_msgs, db->msgs[i].src.mpf.path);
if ((matched_index >= 0) &&
(sorted_paths[matched_index].src.mpf.mtime == db->msgs[i].src.mpf.mtime)) {
/* Treat stale files as though the path has changed. */
file_in_db[matched_index] = 1;
file_in_new_list[i] = 1;
if (matched_index >= 0) {
status = do_stat(sorted_paths + matched_index);
if (status) {
if (sorted_paths[matched_index].src.mpf.mtime == db->msgs[i].src.mpf.mtime) {
/* Treat stale files as though the path has changed. */
file_in_db[matched_index] = 1;
file_in_new_list[i] = 1;
} else {
fprintf(stderr, "mtime failed for '%s'\n", sorted_paths[matched_index].src.mpf.path);
}
} else {
/* This path will get treated as dead, and be re-stated below.
* When that stat fails, the path won't get added to the db. */
}
}
break;
case MTY_MBOX:
......@@ -924,9 +950,17 @@ int update_database(struct database *db, struct msgpath *sorted_paths, int n_msg
any_new = 0;
for (i=0; i<n_msgs; i++) {
if (!file_in_db[i]) {
int status;
any_new = 1;
/* The 'sorted_paths' array is only used for file-per-message folders. */
add_msg_path(db, sorted_paths[i].src.mpf.path, sorted_paths[i].src.mpf.mtime, sorted_paths[i].src.mpf.size);
status = do_stat(sorted_paths + i);
if (status) {
/* We only add files that could be successfully stat()'d as regular
* files. */
add_msg_path(db, sorted_paths[i].src.mpf.path, sorted_paths[i].src.mpf.mtime, sorted_paths[i].src.mpf.size);
} else {
fprintf(stderr, "Cannot add '%s' to database; stat() failed\n", sorted_paths[i].src.mpf.path);
}
}
}
......
......@@ -62,7 +62,7 @@ void free_msgpath_array(struct msgpath_array *x)/*{{{*/
free(x);
}
/*}}}*/
static void add_file_to_list(char *x, unsigned long mtime, size_t message_size, struct msgpath_array *arr) {/*{{{*/
static void add_file_to_list(char *x, struct msgpath_array *arr) {/*{{{*/
char *y = new_string(x);
if (arr->n == arr->max) {
arr->max += 1024;
......@@ -71,8 +71,6 @@ static void add_file_to_list(char *x, unsigned long mtime, size_t message_size,
}
arr->type[arr->n] = MTY_FILE;
arr->paths[arr->n].src.mpf.path = y;
arr->paths[arr->n].src.mpf.mtime = mtime;
arr->paths[arr->n].src.mpf.size = message_size;
++arr->n;
return;
}
......@@ -84,7 +82,6 @@ static void get_maildir_message_paths(char *folder, struct msgpath_array *arr)/*
static char *subdirs[] = {"new", "cur"};
DIR *d;
struct dirent *de;
struct stat sb;
int folder_len = strlen(folder);
/* FIXME : just store mdir-rooted paths in array and have common prefix elsewhere. */
......@@ -100,14 +97,14 @@ static void get_maildir_message_paths(char *folder, struct msgpath_array *arr)/*
while ((de = readdir(d))) {
/* TODO : Perhaps we ought to do some validation on the path here?
i.e. check that the filename looks valid for a maildir message. */
if (!strcmp(de->d_name, ".") ||
!strcmp(de->d_name, "..")) {
continue;
}
strcpy(fname, subdir);
strcat(fname, "/");
strcat(fname, de->d_name);
if (stat(fname, &sb) >= 0) {
if (S_ISREG(sb.st_mode)) {
add_file_to_list(fname, sb.st_mtime, sb.st_size, arr);
}
}
add_file_to_list(fname, arr);
}
closedir(d);
}
......@@ -140,7 +137,6 @@ static void get_mh_message_paths(char *folder, struct msgpath_array *arr)/*{{{*/
char *fname;
DIR *d;
struct dirent *de;
struct stat sb;
int folder_len = strlen(folder);
fname = new_array(char, folder_len + 8 + NAME_MAX);
......@@ -150,12 +146,8 @@ static void get_mh_message_paths(char *folder, struct msgpath_array *arr)/*{{{*/
strcpy(fname, folder);
strcat(fname, "/");
strcat(fname, de->d_name);
if (stat(fname, &sb) >= 0) {
if (S_ISREG(sb.st_mode)) {
if (valid_mh_filename_p(de->d_name)) {
add_file_to_list(fname, sb.st_mtime, sb.st_size, arr);
}
}
if (valid_mh_filename_p(de->d_name)) {
add_file_to_list(fname, arr);
}
}
closedir(d);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment