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 alloc_sprite_map(unsigned int, unsigned int);
|
||||||
SPRITE_MAP_HANDLE free_sprite_map(SPRITE_MAP_HANDLE);
|
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);
|
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)));
|
void log_event(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include "safe-wrappers.h"
|
#include "safe-wrappers.h"
|
||||||
#include "kitty-uthash.h"
|
#include "kitty-uthash.h"
|
||||||
#include "loop-utils.h"
|
#include "loop-utils.h"
|
||||||
|
#include "fast-file-copy.h"
|
||||||
#include "threading.h"
|
#include "threading.h"
|
||||||
#include "cross-platform-random.h"
|
#include "cross-platform-random.h"
|
||||||
#include <structmember.h>
|
#include <structmember.h>
|
||||||
@ -132,8 +133,7 @@ static void
|
|||||||
defrag(DiskCache *self) {
|
defrag(DiskCache *self) {
|
||||||
int new_cache_file = -1;
|
int new_cache_file = -1;
|
||||||
FREE_AFTER_FUNCTION DefragEntry *defrag_entries = NULL;
|
FREE_AFTER_FUNCTION DefragEntry *defrag_entries = NULL;
|
||||||
FREE_AFTER_FUNCTION uint8_t *buf = NULL;
|
AutoFreeFastFileCopyBuffer fcb = {0};
|
||||||
const size_t bufsz = 1024 * 1024;
|
|
||||||
bool lock_released = false, ok = false;
|
bool lock_released = false, ok = false;
|
||||||
|
|
||||||
off_t size_on_disk = size_of_cache_file(self);
|
off_t size_on_disk = size_of_cache_file(self);
|
||||||
@ -164,17 +164,13 @@ defrag(DiskCache *self) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
lseek(new_cache_file, 0, SEEK_SET);
|
lseek(new_cache_file, 0, SEEK_SET);
|
||||||
#ifndef HAS_SENDFILE
|
|
||||||
buf = malloc(bufsz);
|
|
||||||
if (!buf) goto cleanup;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mutex(unlock); lock_released = true;
|
mutex(unlock); lock_released = true;
|
||||||
|
|
||||||
off_t current_pos = 0;
|
off_t current_pos = 0;
|
||||||
for (size_t i = 0; i < num_entries_to_defrag; i++) {
|
for (size_t i = 0; i < num_entries_to_defrag; i++) {
|
||||||
DefragEntry *e = defrag_entries + 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");
|
perror("Failed to copy data to new disk cache file during defrag");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,19 +5,15 @@
|
|||||||
* Distributed under terms of the GPL3 license.
|
* Distributed under terms of the GPL3 license.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "data-types.h"
|
#include "fast-file-copy.h"
|
||||||
#if __linux__
|
#if __linux__
|
||||||
#define HAS_SENDFILE
|
#define HAS_SENDFILE
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAS_SENDFILE
|
|
||||||
#include <sys/sendfile.h>
|
#include <sys/sendfile.h>
|
||||||
#endif
|
#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
|
#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;
|
unsigned num_of_consecutive_zero_returns = 128;
|
||||||
while (len) {
|
while (len) {
|
||||||
off_t r = in_pos;
|
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;
|
num_of_consecutive_zero_returns = 128;
|
||||||
in_pos += n; len -= n;
|
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) {
|
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 (amt_read < 0) {
|
||||||
if (errno == EINTR || errno == EAGAIN) continue;
|
if (errno == EINTR || errno == EAGAIN) continue;
|
||||||
return false;
|
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;
|
len -= amt_read;
|
||||||
in_pos += amt_read;
|
in_pos += amt_read;
|
||||||
uint8_t *p = buf;
|
uint8_t *p = fcb->buf;
|
||||||
while(amt_read) {
|
while(amt_read) {
|
||||||
ssize_t amt_written = write(outfd, p, amt_read);
|
ssize_t amt_written = write(outfd, p, amt_read);
|
||||||
if (amt_written < 0) {
|
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;
|
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
|
#endif
|
||||||
return true;
|
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…
x
Reference in New Issue
Block a user