[sheepdog] [PATCH] test patch: try compress before write to disk
Liu Yuan
namei.unix at gmail.com
Tue Jul 16 11:30:22 CEST 2013
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
collie/Makefile.am | 2 +-
collie/farm/sha1_file.c | 85 +++++++++++++++++++++++++++++++++++------------
2 files changed, 64 insertions(+), 23 deletions(-)
diff --git a/collie/Makefile.am b/collie/Makefile.am
index 2b45b53..b520c1a 100644
--- a/collie/Makefile.am
+++ b/collie/Makefile.am
@@ -32,7 +32,7 @@ collie_SOURCES += debug.c
override CFLAGS := $(subst -pg -gstabs,,$(CFLAGS))
endif
-collie_LDADD = ../lib/libsheepdog.a -lpthread
+collie_LDADD = ../lib/libsheepdog.a -lpthread -lz
collie_DEPENDENCIES = ../lib/libsheepdog.a
noinst_HEADERS = treeview.h collie.h farm/farm.h
diff --git a/collie/farm/sha1_file.c b/collie/farm/sha1_file.c
index dc134a4..3739abf 100644
--- a/collie/farm/sha1_file.c
+++ b/collie/farm/sha1_file.c
@@ -24,9 +24,11 @@
*/
#include <sys/types.h>
#include <sys/xattr.h>
+#include <sys/mman.h>
#include "farm.h"
#include "util.h"
+#include <zlib.h>
static void get_buffer_sha1(void *buf, size_t len, unsigned char *sha1)
{
@@ -149,8 +151,26 @@ bool sha1_file_exist(const unsigned char *sha1)
int sha1_file_write(void *buf, size_t len, unsigned char *outsha1)
{
unsigned char sha1[SHA1_DIGEST_SIZE];
+ unsigned char *compressed;
+ z_stream stream;
+ int size;
+
+ memset(&stream, 0, sizeof(stream));
+ deflateInit(&stream, Z_BEST_COMPRESSION);
+ size = deflateBound(&stream, len);
+ compressed = xmalloc(size);
+
+ stream.next_in = buf;
+ stream.avail_in = len;
+ stream.next_out = compressed;
+ stream.avail_out = size;
+ while (deflate(&stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ deflateEnd(&stream);
+ size = stream.total_out;
+
+ get_buffer_sha1(compressed, size, sha1);
- get_buffer_sha1(buf, len, sha1);
if (sha1_buffer_write(sha1, buf, len) < 0)
return -1;
if (outsha1)
@@ -171,44 +191,65 @@ static int verify_sha1_file(const unsigned char *sha1, void *buf, size_t len)
return 0;
}
-void *sha1_file_read(const unsigned char *sha1, size_t *size)
+static void *map_sha1_file(const unsigned char *sha1, size_t *size)
{
char *filename = sha1_to_path(sha1);
int fd = open(filename, O_RDONLY);
struct stat st;
- void *buf = NULL;
+ void *map;
if (fd < 0) {
perror(filename);
return NULL;
}
if (fstat(fd, &st) < 0) {
- fprintf(stderr, "%m\n");
- goto out;
+ close(fd);
+ return NULL;
}
+ map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+ if (map == MAP_FAILED)
+ return NULL;
+ *size = st.st_size;
+ return map;
+}
- buf = xmalloc(st.st_size);
- if (!buf)
- goto out;
-
- if (xread(fd, buf, st.st_size) != st.st_size) {
- free(buf);
- buf = NULL;
- goto out;
- }
+static void *unpack_sha1_file(void *map, unsigned long mapsize, size_t *size)
+{
+ z_stream stream;
+ unsigned char buffer[512*1024];
+ char *buf;
- if (verify_sha1_file(sha1, buf, st.st_size) < 0) {
- free(buf);
- buf = NULL;
- goto out;
- }
+ memset(&stream, 0, sizeof(stream));
+ stream.next_in = map;
+ stream.avail_in = mapsize;
+ stream.next_out = buffer;
+ stream.avail_out = sizeof(buffer);
- *size = st.st_size;
-out:
- close(fd);
+ inflateInit(&stream);
+ while (inflate(&stream, Z_FINISH) == Z_OK)
+ /* do nothing */;
+ *size = stream.total_out;
+ buf = xmalloc(*size);
+ memcpy(buf, buffer, *size);
+ inflateEnd(&stream);
return buf;
}
+void *sha1_file_read(const unsigned char *sha1, size_t *size)
+{
+ unsigned long mapsize;
+ void *map, *buf;
+
+ map = map_sha1_file(sha1, &mapsize);
+ if (!map)
+ return NULL;
+ if (verify_sha1_file(sha1, map, mapsize) < 0)
+ return NULL;
+ buf = unpack_sha1_file(map, mapsize, size);
+ munmap(map, mapsize);
+ return buf;
+}
int sha1_file_try_delete(const unsigned char *sha1)
{
char *filename = sha1_to_path(sha1);
--
1.7.9.5
More information about the sheepdog
mailing list