From a7c41fa3ae27b567a99b6b5b0aa82223cb1da46d Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Thu, 15 Dec 2011 20:23:19 +0100 Subject: [PATCH] Even more faster write of content files. --- state.c | 20 ++++----- util.c | 123 ++++++++++++++++++++++++++++++-------------------------- util.h | 37 +++++++++-------- 3 files changed, 94 insertions(+), 86 deletions(-) diff --git a/state.c b/state.c index 58235b9e..8cddf74a 100644 --- a/state.c +++ b/state.c @@ -1011,7 +1011,7 @@ void state_write(struct snapraid_state* state) i = i->next; } - sputs("blksize ", f); + sputsl("blksize ", f); sputu32(state->block_size, f); sputeol(f); if (serror(f)) { @@ -1020,9 +1020,9 @@ void state_write(struct snapraid_state* state) } if (state->hash == HASH_MD5) - sputs("checksum md5", f); + sputsl("checksum md5", f); else - sputs("checksum murmur3", f); + sputsl("checksum murmur3", f); sputeol(f); if (serror(f)) { fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno)); @@ -1032,7 +1032,7 @@ void state_write(struct snapraid_state* state) /* for each map */ for(i=state->maplist;i!=0;i=i->next) { struct snapraid_map* map = i->data; - sputs("map ", f); + sputsl("map ", f); sputs(map->name, f); sputc(' ', f); sputu32(map->position, f); @@ -1058,9 +1058,9 @@ void state_write(struct snapraid_state* state) size = file->size; mtime = file->mtime; - inode = file->inode, + inode = file->inode; - sputs("file ", f); + sputsl("file ", f); sputs(disk->name, f); sputc(' ', f); sputu64(size, f); @@ -1081,9 +1081,9 @@ void state_write(struct snapraid_state* state) struct snapraid_block* block = &file->blockvec[k]; if (block_flag_has(block, BLOCK_HAS_PARITY)) { - sputs("blk ", f); + sputsl("blk ", f); } else { - sputs("inv ", f); + sputsl("inv ", f); } if (block_flag_has(block, BLOCK_HAS_HASH)) { @@ -1109,12 +1109,12 @@ void state_write(struct snapraid_state* state) for(j=disk->linklist;j!=0;j=j->next) { struct snapraid_link* link = j->data; - sputs("symlink ", f); + sputsl("symlink ", f); sputs(disk->name, f); sputc(' ', f); sputs(link->sub, f); sputeol(f); - sputs("to ", f); + sputsl("to ", f); sputs(link->linkto, f); sputeol(f); if (serror(f)) { diff --git a/util.c b/util.c index 12ff7c57..1bbf9b10 100644 --- a/util.c +++ b/util.c @@ -20,22 +20,10 @@ #include "util.h" /****************************************************************************/ -/* string */ +/* hex conversion table */ static char strhexset[16] = "0123456789abcdef"; -void strenchex(char* str, const void* void_data, unsigned data_len) -{ - const unsigned char* data = void_data; - unsigned i; - - for(i=0;i> 4]; - *str++ = strhexset[b & 0xF]; - } -} - static unsigned strdecset[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -56,33 +44,6 @@ static unsigned strdecset[256] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -char* strdechex(void* void_data, unsigned data_len, char* str) -{ - unsigned char* data = void_data; - unsigned i; - - for(i=0;i 0xFF) - return str; - - data[0] = b; - - data += 1; - str += 2; - } - - return 0; -} - /****************************************************************************/ /* stream */ @@ -475,9 +436,34 @@ int sgethex(STREAM* f, void* void_data, int size) int sputs(const char* str, STREAM* f) { while (*str) { - if (sputc(*str, f) != 0) + if (sputc(*str++, f) != 0) return -1; - ++str; + } + + return 0; +} + +int swrite(const void* void_data, unsigned size, STREAM* f) +{ + const unsigned char* data = void_data; + + /* if there is enough space in memory */ + if (sptrlookup(f, size)) { + /* optimized version with all the data in memory */ + unsigned char* pos = sptrget(f); + + /* copy it */ + while (size--) { + *pos++ = *data++; + } + + sptrset(f, pos); + } else { + /* standard version using sputc() */ + while (size--) { + if (sputc(*data++, f) != 0) + return -1; + } } return 0; @@ -492,51 +478,74 @@ int sputu32(uint32_t value, STREAM* s) return sputc('0', s); i = sizeof(buf); - buf[--i] = 0; while (value) { buf[--i] = (value % 10) + '0'; value /= 10; } - return sputs(buf + i, s); + return swrite(buf + i, sizeof(buf) - i, s); } int sputu64(uint64_t value, STREAM* s) { char buf[32]; + uint32_t value32; int i; if (!value) return sputc('0', s); - if (value <= 0xFFFFFFFF) - return sputu32((uint32_t)value, s); i = sizeof(buf); - buf[--i] = 0; - while (value) { + while (value > 0xFFFFFFFF) { buf[--i] = (value % 10) + '0'; value /= 10; } - return sputs(buf + i, s); + value32 = (uint32_t)value; + + while (value32) { + buf[--i] = (value32 % 10) + '0'; + value32 /= 10; + } + + return swrite(buf + i, sizeof(buf) - i, s); } int sputhex(const void* void_data, int size, STREAM* f) { const unsigned char* data = void_data; - while (size) { - unsigned b = *data; + /* if there is enough space in memory */ + if (sptrlookup(f, size * 2)) { + /* optimized version with all the data in memory */ + unsigned char* pos = sptrget(f); - if (sputc(strhexset[b >> 4], f) != 0) - return -1; - if (sputc(strhexset[b & 0xF], f) != 0) - return -1; + while (size) { + unsigned b = *data; - ++data; - --size; + *pos++ = strhexset[b >> 4]; + *pos++ = strhexset[b & 0xF]; + + ++data; + --size; + } + + sptrset(f, pos); + } else { + /* standard version using sputc() */ + while (size) { + unsigned b = *data; + + if (sputc(strhexset[b >> 4], f) != 0) + return -1; + if (sputc(strhexset[b & 0xF], f) != 0) + return -1; + + ++data; + --size; + } } return 0; diff --git a/util.h b/util.h index 2ab16c96..5725e413 100644 --- a/util.h +++ b/util.h @@ -18,19 +18,6 @@ #ifndef __UTIL_H #define __UTIL_H -/****************************************************************************/ -/* string */ - -/** - * Encodes to hex. - */ -void strenchex(char* str, const void* void_data, unsigned data_len); - -/** - * Decodes from hex. - */ -char* strdechex(void* void_data, unsigned data_len, char* str); - /****************************************************************************/ /* stream */ @@ -252,7 +239,7 @@ int sgethex(STREAM* f, void* data, int size); /** * Writes a char. Like fputc(). - * Returns 0 on succes or -1 on error. + * Returns 0 on success or -1 on error. */ static inline int sputc(int c, STREAM* s) { @@ -266,7 +253,7 @@ static inline int sputc(int c, STREAM* s) /** * Writes a end of line. - * Returns 0 on succes or -1 on error. + * Returns 0 on success or -1 on error. */ static inline int sputeol(STREAM* s) { @@ -279,25 +266,37 @@ static inline int sputeol(STREAM* s) /** * Writes a string. - * Returns 0 on succes or -1 on error. + * Returns 0 on success or -1 on error. */ int sputs(const char* str, STREAM* f); +/** + * Write a sized string. + * Returns 0 on success or -1 on error. + */ +int swrite(const void* data, unsigned size, STREAM* f); + +/** + * Write a string literal (constant string). + * Returns 0 on success or -1 on error. + */ +#define sputsl(str, f) swrite(str, sizeof(str) - 1, f) + /** * Writes a 32 bit number. - * Returns 0 on succes or -1 on error. + * Returns 0 on success or -1 on error. */ int sputu32(uint32_t value, STREAM* s); /** * Writes a 64 bit number. - * Returns 0 on succes or -1 on error. + * Returns 0 on success or -1 on error. */ int sputu64(uint64_t value, STREAM* s); /** * Writes a hexadecimal string of fixed length. - * Returns 0 on succes or -1 on error. + * Returns 0 on success or -1 on error. */ int sputhex(const void* void_data, int size, STREAM* s);