diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-03-17 14:17:35 +0200 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-03-17 14:17:35 +0200 |
commit | 207bff6e6cbc1509b39ce14513f412548d9c2d97 (patch) | |
tree | 013cbf791f5594dd4989bfb33bcb16ce52d96e06 | |
parent | 7735cc644d342e39b8b2b71da6890656d1846fab (diff) | |
download | apk-tools-207bff6e6cbc1509b39ce14513f412548d9c2d97.tar.gz apk-tools-207bff6e6cbc1509b39ce14513f412548d9c2d97.tar.bz2 apk-tools-207bff6e6cbc1509b39ce14513f412548d9c2d97.tar.xz apk-tools-207bff6e6cbc1509b39ce14513f412548d9c2d97.zip |
io: implement write cache
speeds up writing of package / file database.
-rw-r--r-- | src/io.c | 39 |
1 files changed, 35 insertions, 4 deletions
@@ -399,16 +399,16 @@ struct apk_istream *apk_istream_from_file_gz(const char *file) struct apk_fd_ostream { struct apk_ostream os; int fd; + size_t bytes; + char buffer[1024]; }; -static size_t fdo_write(void *stream, const void *ptr, size_t size) +static size_t safe_write(int fd, const void *ptr, size_t size) { - struct apk_fd_ostream *fos = - container_of(stream, struct apk_fd_ostream, os); size_t i = 0, r; while (i < size) { - r = write(fos->fd, ptr + i, size - i); + r = write(fd, ptr + i, size - i); if (r < 0) return r; if (r == 0) @@ -419,11 +419,42 @@ static size_t fdo_write(void *stream, const void *ptr, size_t size) return i; } +static int fdo_flush(struct apk_fd_ostream *fos) +{ + if (fos->bytes == 0) + return 0; + + if (safe_write(fos->fd, fos->buffer, fos->bytes) != fos->bytes) + return -1; + + fos->bytes = 0; + return 0; +} + +static size_t fdo_write(void *stream, const void *ptr, size_t size) +{ + struct apk_fd_ostream *fos = + container_of(stream, struct apk_fd_ostream, os); + + if (size + fos->bytes >= sizeof(fos->buffer)) { + if (fdo_flush(fos)) + return -1; + if (size >= sizeof(fos->buffer) / 2) + return safe_write(fos->fd, ptr, size); + } + + memcpy(&fos->buffer[fos->bytes], ptr, size); + fos->bytes += size; + + return size; +} + static void fdo_close(void *stream) { struct apk_fd_ostream *fos = container_of(stream, struct apk_fd_ostream, os); + fdo_flush(fos); close(fos->fd); free(fos); } |