mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-22 03:57:30 +03:00
Only malloc the buffer for fast file copy when needed
This commit is contained in:
parent
732ff7ee58
commit
bd21b79959
@ -368,5 +368,4 @@ void play_canberra_sound(const char *which_sound, const char *event_id, bool is_
|
||||
SPRITE_MAP_HANDLE alloc_sprite_map(unsigned int, unsigned int);
|
||||
SPRITE_MAP_HANDLE free_sprite_map(SPRITE_MAP_HANDLE);
|
||||
const char* get_hyperlink_for_id(const HYPERLINK_POOL_HANDLE, hyperlink_id_type id, bool only_url);
|
||||
bool copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf, size_t bufsz);
|
||||
void log_event(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "safe-wrappers.h"
|
||||
#include "kitty-uthash.h"
|
||||
#include "loop-utils.h"
|
||||
#include "fast-file-copy.h"
|
||||
#include "threading.h"
|
||||
#include "cross-platform-random.h"
|
||||
#include <structmember.h>
|
||||
@ -132,8 +133,7 @@ static void
|
||||
defrag(DiskCache *self) {
|
||||
int new_cache_file = -1;
|
||||
FREE_AFTER_FUNCTION DefragEntry *defrag_entries = NULL;
|
||||
FREE_AFTER_FUNCTION uint8_t *buf = NULL;
|
||||
const size_t bufsz = 1024 * 1024;
|
||||
AutoFreeFastFileCopyBuffer fcb = {0};
|
||||
bool lock_released = false, ok = false;
|
||||
|
||||
off_t size_on_disk = size_of_cache_file(self);
|
||||
@ -164,17 +164,13 @@ defrag(DiskCache *self) {
|
||||
goto cleanup;
|
||||
}
|
||||
lseek(new_cache_file, 0, SEEK_SET);
|
||||
#ifndef HAS_SENDFILE
|
||||
buf = malloc(bufsz);
|
||||
if (!buf) goto cleanup;
|
||||
#endif
|
||||
|
||||
mutex(unlock); lock_released = true;
|
||||
|
||||
off_t current_pos = 0;
|
||||
for (size_t i = 0; i < num_entries_to_defrag; i++) {
|
||||
DefragEntry *e = defrag_entries + i;
|
||||
if (!copy_between_files(self->cache_file_fd, new_cache_file, e->old_offset, e->data_sz, buf, bufsz)) {
|
||||
if (!copy_between_files(self->cache_file_fd, new_cache_file, e->old_offset, e->data_sz, &fcb)) {
|
||||
perror("Failed to copy data to new disk cache file during defrag");
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -5,19 +5,15 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "data-types.h"
|
||||
#include "fast-file-copy.h"
|
||||
#if __linux__
|
||||
#define HAS_SENDFILE
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SENDFILE
|
||||
#include <sys/sendfile.h>
|
||||
#endif
|
||||
|
||||
bool
|
||||
copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf, size_t bufsz) {
|
||||
#ifdef HAS_SENDFILE
|
||||
(void)buf; (void)bufsz;
|
||||
static bool
|
||||
copy_with_sendfile(int infd, int outfd, off_t in_pos, size_t len) {
|
||||
unsigned num_of_consecutive_zero_returns = 128;
|
||||
while (len) {
|
||||
off_t r = in_pos;
|
||||
@ -34,9 +30,19 @@ copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf,
|
||||
num_of_consecutive_zero_returns = 128;
|
||||
in_pos += n; len -= n;
|
||||
}
|
||||
#else
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool
|
||||
copy_with_buffer(int infd, int outfd, off_t in_pos, size_t len, FastFileCopyBuffer *fcb) {
|
||||
if (!fcb->buf) {
|
||||
fcb->sz = 16 * 1024;
|
||||
fcb->buf = malloc(fcb->sz);
|
||||
if (!fcb->buf) return false;
|
||||
}
|
||||
while (len) {
|
||||
ssize_t amt_read = pread(infd, buf, MIN(len, bufsz), in_pos);
|
||||
ssize_t amt_read = pread(infd, fcb->buf, MIN(len, fcb->sz), in_pos);
|
||||
if (amt_read < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN) continue;
|
||||
return false;
|
||||
@ -47,7 +53,7 @@ copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf,
|
||||
}
|
||||
len -= amt_read;
|
||||
in_pos += amt_read;
|
||||
uint8_t *p = buf;
|
||||
uint8_t *p = fcb->buf;
|
||||
while(amt_read) {
|
||||
ssize_t amt_written = write(outfd, p, amt_read);
|
||||
if (amt_written < 0) {
|
||||
@ -62,6 +68,17 @@ copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf,
|
||||
p += amt_written;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#undef bufsz
|
||||
}
|
||||
|
||||
bool
|
||||
copy_between_files(int infd, int outfd, off_t in_pos, size_t len, FastFileCopyBuffer *fcb) {
|
||||
#ifdef HAS_SENDFILE
|
||||
(void)fcb;
|
||||
return copy_with_sendfile(infd, outfd, in_pos, len);
|
||||
#else
|
||||
return copy_with_buffer(infd, outfd, in_pos, len, fcb);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
22
kitty/fast-file-copy.h
Normal file
22
kitty/fast-file-copy.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "data-types.h"
|
||||
|
||||
typedef struct FastFileCopyBuffer {
|
||||
uint8_t *buf;
|
||||
size_t sz;
|
||||
} FastFileCopyBuffer;
|
||||
|
||||
static inline void
|
||||
free_fast_file_copy_buffer(FastFileCopyBuffer *fcb) { free(fcb->buf); }
|
||||
|
||||
#define FREE_FCB_AFTER_FUNCTION __attribute__ ((__cleanup__(free_fast_file_copy_buffer)))
|
||||
#define AutoFreeFastFileCopyBuffer FREE_FCB_AFTER_FUNCTION FastFileCopyBuffer
|
||||
|
||||
bool copy_between_files(int infd, int outfd, off_t in_pos, size_t len, FastFileCopyBuffer *fcb);
|
Loading…
Reference in New Issue
Block a user