Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cache stat(2) calls #760

Merged
merged 1 commit into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 54 additions & 41 deletions src/filelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ feh_file *feh_file_new(char *filename)
newfile->name = estrdup(s + 1);
else
newfile->name = estrdup(filename);
newfile->size = -1;
newfile->mtime = 0;
newfile->info = NULL;
#ifdef HAVE_LIBEXIF
newfile->ed = NULL;
Expand Down Expand Up @@ -89,7 +91,6 @@ feh_file_info *feh_file_info_new(void)

info->width = 0;
info->height = 0;
info->size = 0;
info->pixels = 0;
info->has_alpha = 0;
info->format = NULL;
Expand Down Expand Up @@ -305,7 +306,7 @@ void delete_rm_files(void)
return;
}

gib_list *feh_file_info_preload(gib_list * list)
gib_list *feh_file_info_preload(gib_list * list, int load_images)
{
gib_list *l;
feh_file *file = NULL;
Expand All @@ -314,20 +315,27 @@ gib_list *feh_file_info_preload(gib_list * list)
for (l = list; l; l = l->next) {
file = FEH_FILE(l->data);
D(("file %p, file->next %p, file->name %s\n", l, l->next, file->name));
if (feh_file_info_load(file, NULL)) {
D(("Failed to load file %p\n", file));
remove_list = gib_list_add_front(remove_list, l);
if (opt.verbose)
feh_display_status('x');
} else if (((unsigned int)file->info->width < opt.min_width)
|| ((unsigned int)file->info->width > opt.max_width)
|| ((unsigned int)file->info->height < opt.min_height)
|| ((unsigned int)file->info->height > opt.max_height)) {
remove_list = gib_list_add_front(remove_list, l);
if (opt.verbose)
feh_display_status('s');
} else if (opt.verbose)
feh_display_status('.');
if (load_images) {
if (feh_file_info_load(file, NULL)) {
D(("Failed to load file %p\n", file));
remove_list = gib_list_add_front(remove_list, l);
if (opt.verbose)
feh_display_status('x');
} else if (((unsigned int)file->info->width < opt.min_width)
|| ((unsigned int)file->info->width > opt.max_width)
|| ((unsigned int)file->info->height < opt.min_height)
|| ((unsigned int)file->info->height > opt.max_height)) {
remove_list = gib_list_add_front(remove_list, l);
if (opt.verbose)
feh_display_status('s');
} else if (opt.verbose)
feh_display_status('.');
} else {
if (feh_file_stat(file)) {
D(("Failed to stat file %p\n", file));
remove_list = gib_list_add_front(remove_list, l);
}
}
if (sig_exit) {
feh_display_status(0);
exit(sig_exit);
Expand All @@ -348,23 +356,36 @@ gib_list *feh_file_info_preload(gib_list * list)
return(list);
}

int feh_file_info_load(feh_file * file, Imlib_Image im)
int feh_file_stat(feh_file * file)
{
struct stat st;

errno = 0;
if (stat(file->filename, &st)) {
feh_print_stat_error(file->filename);
return(1);
}

file->mtime = st.st_mtime;

file->size = st.st_size;

return(0);
}

int feh_file_info_load(feh_file * file, Imlib_Image im)
{
int need_free = 1;
Imlib_Image im1;

if (feh_file_stat(file))
return(1);

D(("im is %p\n", im));

if (im)
need_free = 0;

errno = 0;
if (stat(file->filename, &st)) {
feh_print_stat_error(file->filename);
return(1);
}

if (im)
im1 = im;
else if (!feh_load_image(&im1, file) || !im1)
Expand All @@ -381,8 +402,6 @@ int feh_file_info_load(feh_file * file, Imlib_Image im)

file->info->format = estrdup(gib_imlib_image_format(im1));

file->info->size = st.st_size;

if (need_free)
gib_imlib_free_image_and_decache(im1);
return(0);
Expand Down Expand Up @@ -434,20 +453,8 @@ int feh_cmp_dirname(void *file1, void *file2)
/* Return -1 if file1 is _newer_ than file2 */
int feh_cmp_mtime(void *file1, void *file2)
{
struct stat s1, s2;

if (stat(FEH_FILE(file1)->filename, &s1)) {
feh_print_stat_error(FEH_FILE(file1)->filename);
return(-1);
}

if (stat(FEH_FILE(file2)->filename, &s2)) {
feh_print_stat_error(FEH_FILE(file2)->filename);
return(-1);
}

/* gib_list_sort is not stable, so explicitly return 0 as -1 */
return(s1.st_mtime >= s2.st_mtime ? -1 : 1);
return(FEH_FILE(file1)->mtime >= FEH_FILE(file2)->mtime ? -1 : 1);
}

int feh_cmp_width(void *file1, void *file2)
Expand All @@ -467,7 +474,7 @@ int feh_cmp_pixels(void *file1, void *file2)

int feh_cmp_size(void *file1, void *file2)
{
return((FEH_FILE(file1)->info->size - FEH_FILE(file2)->info->size));
return((FEH_FILE(file1)->size - FEH_FILE(file2)->size));
}

int feh_cmp_format(void *file1, void *file2)
Expand All @@ -486,10 +493,16 @@ void feh_prepare_filelist(void)
* is set and we're in thumbnail mode, we need to filter images first so
* we can create a properly sized thumbnail list.
*/
if (opt.list || opt.preload || opt.customlist || (opt.sort > SORT_MTIME)
if (opt.list || opt.preload || opt.customlist || (opt.sort >= SORT_WIDTH)
|| (opt.filter_by_dimensions && (opt.index || opt.thumbs || opt.bgmode))) {
/* For these sort options, we have to preload images */
filelist = feh_file_info_preload(filelist);
filelist = feh_file_info_preload(filelist, TRUE);
if (!gib_list_length(filelist))
show_mini_usage();
} else if (opt.sort >= SORT_SIZE) {
/* For these sort options, we need stat(2) information on the files,
* but there is no need to load the images. */
filelist = feh_file_info_preload(filelist, FALSE);
if (!gib_list_length(filelist))
show_mini_usage();
}
Expand Down
10 changes: 6 additions & 4 deletions src/filelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ struct __feh_file {
char *name;

/* info stuff */
time_t mtime;
int size;
feh_file_info *info; /* only set when needed */
#ifdef HAVE_LIBEXIF
ExifData *ed;
Expand All @@ -45,7 +47,6 @@ struct __feh_file {
struct __feh_file_info {
int width;
int height;
int size;
int pixels;
unsigned char has_alpha;
char *format;
Expand All @@ -71,11 +72,11 @@ enum sort_type {
SORT_NAME,
SORT_FILENAME,
SORT_DIRNAME,
SORT_SIZE, // everything after SORT_SIZE requires stat(2) information on the filelist
SORT_MTIME,
SORT_WIDTH,
SORT_WIDTH, // everything after SORT_WIDTH requires preloading the images in the filelist
SORT_HEIGHT,
SORT_PIXELS,
SORT_SIZE,
SORT_FORMAT
};

Expand All @@ -88,7 +89,8 @@ int file_selector_all(const struct dirent *unused);
void add_file_to_filelist_recursively(char *origpath, unsigned char level);
void add_file_to_rm_filelist(char *file);
void delete_rm_files(void);
gib_list *feh_file_info_preload(gib_list * list);
gib_list *feh_file_info_preload(gib_list * list, int load_images);
int feh_file_stat(feh_file * file);
int feh_file_info_load(feh_file * file, Imlib_Image im);
void feh_file_dirname(char *dst, feh_file * f, int maxlen);
void feh_prepare_filelist(void);
Expand Down
2 changes: 1 addition & 1 deletion src/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void init_list_mode(void)
file->info->height,
format_size(file->info->pixels));
printf("\t%s\t%c\t%s\n",
format_size(file->info->size),
format_size(file->size),
file->info->has_alpha ? 'X' : '-', file->filename);
}

Expand Down
4 changes: 2 additions & 2 deletions src/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ void feh_menu_draw_submenu_at(int x, int y, Imlib_Image dst, int ox, int oy)
for (int i= 0; i <= 3; i++) {
imlib_image_draw_line(x+i, y+3+i, x+i, y+9-i, 0);
}

return;
}

Expand Down Expand Up @@ -1401,7 +1401,7 @@ static feh_menu *feh_menu_func_gen_info(feh_menu * m)
if (!file->info)
feh_file_info_load(file, im);
if (file->info) {
snprintf(buffer, sizeof(buffer), "Size: %dKb", file->info->size / 1024);
snprintf(buffer, sizeof(buffer), "Size: %dKb", file->size / 1024);
feh_menu_add_entry(mm, buffer, NULL, 0, 0, NULL);
snprintf(buffer, sizeof(buffer), "Dimensions: %dx%d", file->info->width, file->info->height);
feh_menu_add_entry(mm, buffer, NULL, 0, 0, NULL);
Expand Down
8 changes: 4 additions & 4 deletions src/slideshow.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,14 +496,14 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid)
}
break;
case 's':
if (file && (file->info || !feh_file_info_load(file, NULL))) {
snprintf(buf, sizeof(buf), "%d", file->info->size);
if (file && (file->size >= 0 || !feh_file_stat(file))) {
snprintf(buf, sizeof(buf), "%d", file->size);
strncat(ret, buf, sizeof(ret) - strlen(ret) - 1);
}
break;
case 'S':
if (file && (file->info || !feh_file_info_load(file, NULL))) {
strncat(ret, format_size(file->info->size), sizeof(ret) - strlen(ret) - 1);
if (file && (file->size >= 0 || !feh_file_stat(file))) {
strncat(ret, format_size(file->size), sizeof(ret) - strlen(ret) - 1);
}
break;
case 't':
Expand Down
Loading