Even more faster write of content files.

This commit is contained in:
Andrea Mazzoleni 2011-12-15 20:23:19 +01:00
parent 98fc24c195
commit a7c41fa3ae
3 changed files with 94 additions and 86 deletions

20
state.c
View file

@ -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)) {

123
util.c
View file

@ -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<data_len;++i) {
unsigned char b = data[i];
*str++ = strhexset[b >> 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<data_len;++i) {
unsigned b0;
unsigned b1;
unsigned b;
b0 = strdecset[(unsigned char)str[0]];
b1 = strdecset[(unsigned char)str[1]];
b = (b0 << 4) | b1;
if (b > 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;

37
util.h
View file

@ -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);