Skip to content

Commit

Permalink
perf: precache small images to avoid cache misses; use `symlink_metad…
Browse files Browse the repository at this point in the history
…ata` instead of `metadata` (#367)
  • Loading branch information
sxyazi committed Nov 15, 2023
1 parent 5968b82 commit ff30b24
Show file tree
Hide file tree
Showing 10 changed files with 16 additions and 30 deletions.
2 changes: 1 addition & 1 deletion yazi-adaptor/src/adaptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl Adaptor {

pub async fn image_show(self, mut path: &Path, rect: Rect) -> Result<()> {
let cache = PREVIEW.cache(path, 0);
if fs::metadata(&cache).await.is_ok() {
if fs::symlink_metadata(&cache).await.is_ok() {
path = cache.as_path();
}

Expand Down
22 changes: 4 additions & 18 deletions yazi-adaptor/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use yazi_shared::Term;
pub struct Image;

impl Image {
pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
pub(super) async fn downscale(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
let (w, h) = Term::ratio()
.map(|(w, h)| {
let (w, h) = ((size.0 as f64 * w) as u32, (size.1 as f64 * h) as u32);
Expand All @@ -30,33 +30,19 @@ impl Image {
img.await?
}

pub async fn precache(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<bool> {
pub async fn precache(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<()> {
let cache = cache.as_ref().to_owned();
let result = tokio::task::spawn_blocking(move || {
let img = image::load_from_memory(&img)?;
let (w, h) = (PREVIEW.max_width, PREVIEW.max_height);

if img.width() <= w && img.height() <= h {
return Ok(false);
}

match img.resize(w, h, FilterType::Triangle) {
Ok(match img.resize(w, h, FilterType::Triangle) {
DynamicImage::ImageRgb8(buf) => buf.save_with_format(cache, ImageFormat::Jpeg),
DynamicImage::ImageRgba8(buf) => buf.save_with_format(cache, ImageFormat::Jpeg),
buf => buf.to_rgb8().save_with_format(cache, ImageFormat::Jpeg),
}?;

Ok(true)
}?)
});

result.await?
}

#[inline]
pub async fn precache_anyway(img: Arc<Vec<u8>>, cache: impl AsRef<Path>) -> Result<()> {
Ok(match Self::precache(img.clone(), &cache).await {
Ok(true) => (),
_ => fs::write(cache, &*img).await?,
})
}
}
2 changes: 1 addition & 1 deletion yazi-adaptor/src/iterm2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub(super) struct Iterm2;

impl Iterm2 {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let img = Image::downscale(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;

Self::image_hide(rect)?;
Expand Down
2 changes: 1 addition & 1 deletion yazi-adaptor/src/kitty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ pub(super) struct Kitty;

impl Kitty {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let img = Image::downscale(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;

Self::image_hide(rect)?;
Expand Down
2 changes: 1 addition & 1 deletion yazi-adaptor/src/kitty_old.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub(super) struct KittyOld;

impl KittyOld {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let img = Image::downscale(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;

Self::image_hide()?;
Expand Down
2 changes: 1 addition & 1 deletion yazi-adaptor/src/sixel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(super) struct Sixel;

impl Sixel {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let img = Image::downscale(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;

Self::image_hide(rect)?;
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/external/pdftoppm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>, skip: usize) -> Result
return if pages > 0 { Err(PeekError::Exceed(pages - 1)) } else { Err(s.to_string().into()) };
}

Ok(Image::precache_anyway(Arc::new(output.stdout), dest).await?)
Ok(Image::precache(Arc::new(output.stdout), dest).await?)
}
2 changes: 1 addition & 1 deletion yazi-core/src/manager/commands/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl Manager {

let mut failed = Vec::new();
for (o, n) in todo {
if fs::metadata(&n).await.is_ok() {
if fs::symlink_metadata(&n).await.is_ok() {
failed.push((o, n, anyhow!("Destination already exists")));
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions yazi-core/src/preview/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl Provider {

pub(super) async fn video(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
let cache = PREVIEW.cache(path, skip);
if fs::metadata(&cache).await.is_err() {
if fs::symlink_metadata(&cache).await.is_err() {
external::ffmpegthumbnailer(path, &cache, skip).await?;
}

Expand All @@ -57,7 +57,7 @@ impl Provider {

pub(super) async fn pdf(path: &Path, skip: usize) -> Result<PreviewData, PeekError> {
let cache = PREVIEW.cache(path, skip);
if fs::metadata(&cache).await.is_err() {
if fs::symlink_metadata(&cache).await.is_err() {
external::pdftoppm(path, &cache, skip).await?;
}

Expand Down
6 changes: 3 additions & 3 deletions yazi-core/src/tasks/workers/precache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl Precache {
match task {
PrecacheOp::Image(task) => {
let cache = PREVIEW.cache(&task.target, 0);
if fs::metadata(&cache).await.is_ok() {
if fs::symlink_metadata(&cache).await.is_ok() {
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
}
if let Ok(img) = fs::read(&task.target).await {
Expand All @@ -85,7 +85,7 @@ impl Precache {
}
PrecacheOp::Video(task) => {
let cache = PREVIEW.cache(&task.target, 0);
if fs::metadata(&cache).await.is_ok() {
if fs::symlink_metadata(&cache).await.is_ok() {
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
}

Expand All @@ -94,7 +94,7 @@ impl Precache {
}
PrecacheOp::Pdf(task) => {
let cache = PREVIEW.cache(&task.target, 0);
if fs::metadata(&cache).await.is_ok() {
if fs::symlink_metadata(&cache).await.is_ok() {
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
}

Expand Down

0 comments on commit ff30b24

Please sign in to comment.