From d7b9d4dbbccc381c1634d77bee20f0adf4119551 Mon Sep 17 00:00:00 2001 From: TapTap Date: Sun, 19 Jul 2026 17:04:05 +0200 Subject: [PATCH] fix: apply clang-format to merged code from main --- src/client/client_cli.c | 6 +- src/client/client_send.c | 91 ++++++++++++++--------- src/shared/config.c | 57 +++++++++----- src/shared/delta.c | 156 ++++++++++++++++++++------------------- src/shared/delta.h | 61 +++++++-------- src/shared/file.c | 118 +++++++++++++++++++---------- src/shared/file.h | 4 +- tests/test_delta.c | 86 +++++++++++---------- 8 files changed, 333 insertions(+), 246 deletions(-) diff --git a/src/client/client_cli.c b/src/client/client_cli.c index ecf152b..eaeddf8 100644 --- a/src/client/client_cli.c +++ b/src/client/client_cli.c @@ -38,8 +38,10 @@ static void print_usage(void) { printf(" --min-size Skip files smaller than n bytes\n"); printf(" --incremental Skip files unchanged since last transfer\n"); printf(" --delta Delta transfer for changed files (requires --incremental)\n"); - printf(" --delta-block Delta block size in bytes (default: %d)\n", DELTA_BLOCK_SIZE_DEFAULT); - printf(" --delta-max Max file size for delta transfer (default: %llu)\n", DELTA_MAX_FILE_SIZE); + printf(" --delta-block Delta block size in bytes (default: %d)\n", + DELTA_BLOCK_SIZE_DEFAULT); + printf(" --delta-max Max file size for delta transfer (default: %llu)\n", + DELTA_MAX_FILE_SIZE); printf(" -m Enable multithreading\n"); printf(" -s Enable chunk serialization\n"); printf(" -f Enable sendfile (TCP only, not with -c or -s)\n"); diff --git a/src/client/client_send.c b/src/client/client_send.c index b682828..8b5bb4a 100644 --- a/src/client/client_send.c +++ b/src/client/client_send.c @@ -22,11 +22,12 @@ #include #include -static int incremental_check(Client *client, File *file, - DeltaSignature **out_sig) { +static int incremental_check(Client* client, File* file, DeltaSignature** out_sig) { *out_sig = NULL; - if (!send_status(client->file_descriptor, STATUS_CHECK)) return -1; - if (!send_str(client->file_descriptor, file->path)) return -1; + if (!send_status(client->file_descriptor, STATUS_CHECK)) + return -1; + if (!send_str(client->file_descriptor, file->path)) + return -1; unsigned long long fsize = file->data->size; long long mtime = file->metadata ? file->metadata->mtime_sec : 0; if (!send_n_data(client->file_descriptor, &fsize, sizeof(fsize))) @@ -40,13 +41,16 @@ static int incremental_check(Client *client, File *file, log_message(LOG_LEVEL_ERROR, "Server reported error for file"); return -1; } - if (s == STATUS_OK) return 1; + if (s == STATUS_OK) + return 1; if (s == STATUS_DELTA_SIGNATURE) { - Data *sig_data = receive_data(client->file_descriptor); - if (!sig_data) return -1; - DeltaSignature *sig = delta_signature_deserialize(sig_data); + Data* sig_data = receive_data(client->file_descriptor); + if (!sig_data) + return -1; + DeltaSignature* sig = delta_signature_deserialize(sig_data); data_destroy(sig_data); - if (!sig) return -1; + if (!sig) + return -1; *out_sig = sig; return 2; } @@ -57,27 +61,29 @@ static int incremental_check(Client *client, File *file, return 0; } -static int send_delta(Client *client, File *file, DeltaSignature *sig, - Config *config) { - Delta *delta = delta_compute(file->data->data, file->data->size, - sig, config->delta_block_size); - if (!delta) return 1; +static int send_delta(Client* client, File* file, DeltaSignature* sig, Config* config) { + Delta* delta = delta_compute(file->data->data, file->data->size, sig, config->delta_block_size); + if (!delta) + return 1; if (!delta_is_worthwhile(delta, file->data->size)) { delta_destroy(delta); - if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1; + if (!send_status(client->file_descriptor, STATUS_NEXT)) + return -1; return 1; } - Data *delta_data = delta_serialize(delta); + Data* delta_data = delta_serialize(delta); delta_destroy(delta); - if (!delta_data) return -1; + if (!delta_data) + return -1; - Data *to_send = delta_data; + Data* to_send = delta_data; if (config->use_compression) { to_send = data_compress(delta_data, config->compression_level); data_destroy(delta_data); - if (!to_send) return -1; + if (!to_send) + return -1; } bool ok = send_status(client->file_descriptor, STATUS_DELTA_DATA) && @@ -90,19 +96,26 @@ static int send_delta(Client *client, File *file, DeltaSignature *sig, return ok ? 0 : -1; } -typedef bool (*file_send_fn)(File *, int, bool, int, bool); +typedef bool (*file_send_fn)(File*, int, bool, int, bool); -static int send_file_incremental(Client *client, File *file, Config *config, - file_send_fn send_fn) { - DeltaSignature *sig = NULL; +static int send_file_incremental(Client* client, File* file, Config* config, file_send_fn send_fn) { + DeltaSignature* sig = NULL; int rc = incremental_check(client, file, &sig); - if (rc < 0) { delta_signature_destroy(sig); return -1; } - if (rc == 1) { delta_signature_destroy(sig); return 1; } + if (rc < 0) { + delta_signature_destroy(sig); + return -1; + } + if (rc == 1) { + delta_signature_destroy(sig); + return 1; + } if (rc == 2 && config->use_delta) { int drc = send_delta(client, file, sig, config); delta_signature_destroy(sig); - if (drc == 0) return 0; - if (drc < 0) return -1; + if (drc == 0) + return 0; + if (drc < 0) + return -1; } else { delta_signature_destroy(sig); } @@ -112,7 +125,7 @@ static int send_file_incremental(Client *client, File *file, Config *config, return 0; } -int send_chunk(Client *client, Chunk *chunk, Config *config) { +int send_chunk(Client* client, Chunk* chunk, Config* config) { if (config->use_chunk_serialization) { if (!send_status(client->file_descriptor, STATUS_CHUNK)) return -1; @@ -133,12 +146,16 @@ int send_chunk(Client *client, Chunk *chunk, Config *config) { for (int i = 0; i < chunk->element_count; i++) { if (config->use_incremental) { int rc = send_file_incremental(client, chunk->items[i], config, - (file_send_fn)file_send_sendfile); - if (rc == 1) continue; - if (rc < 0) return -1; + (file_send_fn)file_send_sendfile); + if (rc == 1) + continue; + if (rc < 0) + return -1; } else { - if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1; - if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata, 0, true)) + if (!send_status(client->file_descriptor, STATUS_NEXT)) + return -1; + if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata, 0, + true)) return -1; } } @@ -146,9 +163,11 @@ int send_chunk(Client *client, Chunk *chunk, Config *config) { for (int i = 0; i < chunk->element_count; i++) { if (config->use_incremental) { int rc = send_file_incremental(client, chunk->items[i], config, - (file_send_fn)file_send_single_calls); - if (rc == 1) continue; - if (rc < 0) return -1; + (file_send_fn)file_send_single_calls); + if (rc == 1) + continue; + if (rc < 0) + return -1; } else { if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1; diff --git a/src/shared/config.c b/src/shared/config.c index 42aaa41..d16761d 100644 --- a/src/shared/config.c +++ b/src/shared/config.c @@ -92,22 +92,38 @@ void config_delete(Config* config) { } bool config_send(int file_descriptor, const Config* config) { - if (!send_str(file_descriptor, config->version)) return false; - if (!send_str(file_descriptor, config->send_directory)) return false; - if (!send_str(file_descriptor, config->receive_root_directory)) return false; - if (!send_int(file_descriptor, config->save_to_disk)) return false; - if (!send_int(file_descriptor, config->use_multithreading)) return false; - if (!send_int(file_descriptor, config->use_chunk_serialization)) return false; - if (!send_int(file_descriptor, config->use_compression)) return false; - if (!send_int(file_descriptor, config->use_metadata)) return false; - if (!send_int(file_descriptor, config->compression_level)) return false; - if (!send_int(file_descriptor, (int)config->chunk_size)) return false; - if (!send_int(file_descriptor, config->use_sendfile)) return false; - if (!send_int(file_descriptor, config->use_delete)) return false; - if (!send_int(file_descriptor, config->use_incremental)) return false; - if (!send_int(file_descriptor, config->use_delta)) return false; - if (!send_int(file_descriptor, (int)config->delta_block_size)) return false; - if (!send_n_data(file_descriptor, &config->delta_max_file_size, sizeof(unsigned long long))) return false; + if (!send_str(file_descriptor, config->version)) + return false; + if (!send_str(file_descriptor, config->send_directory)) + return false; + if (!send_str(file_descriptor, config->receive_root_directory)) + return false; + if (!send_int(file_descriptor, config->save_to_disk)) + return false; + if (!send_int(file_descriptor, config->use_multithreading)) + return false; + if (!send_int(file_descriptor, config->use_chunk_serialization)) + return false; + if (!send_int(file_descriptor, config->use_compression)) + return false; + if (!send_int(file_descriptor, config->use_metadata)) + return false; + if (!send_int(file_descriptor, config->compression_level)) + return false; + if (!send_int(file_descriptor, (int)config->chunk_size)) + return false; + if (!send_int(file_descriptor, config->use_sendfile)) + return false; + if (!send_int(file_descriptor, config->use_delete)) + return false; + if (!send_int(file_descriptor, config->use_incremental)) + return false; + if (!send_int(file_descriptor, config->use_delta)) + return false; + if (!send_int(file_descriptor, (int)config->delta_block_size)) + return false; + if (!send_n_data(file_descriptor, &config->delta_max_file_size, sizeof(unsigned long long))) + return false; Status status; if (!receive_status(file_descriptor, &status)) return false; @@ -179,11 +195,14 @@ Config* config_receive(int file_descriptor) { if (!receive_int(file_descriptor, &tmp)) goto error; config->use_incremental = tmp; - if (!receive_int(file_descriptor, &tmp)) goto error; + if (!receive_int(file_descriptor, &tmp)) + goto error; config->use_delta = tmp; - if (!receive_int(file_descriptor, &tmp)) goto error; + if (!receive_int(file_descriptor, &tmp)) + goto error; config->delta_block_size = (uint32_t)tmp; - if (!receive_n_data(file_descriptor, &config->delta_max_file_size, sizeof(unsigned long long))) goto error; + if (!receive_n_data(file_descriptor, &config->delta_max_file_size, sizeof(unsigned long long))) + goto error; config->show_progress = false; config->dry_run = false; config->ssh_port = 22; diff --git a/src/shared/delta.c b/src/shared/delta.c index fc13a1e..6a94eaf 100644 --- a/src/shared/delta.c +++ b/src/shared/delta.c @@ -7,8 +7,8 @@ #define XXH_IMPLEMENTATION #include -uint32_t delta_adler32(const void *data, uint32_t len) { - const uint8_t *p = (const uint8_t *)data; +uint32_t delta_adler32(const void* data, uint32_t len) { + const uint8_t* p = (const uint8_t*)data; uint32_t s1 = 1; uint32_t s2 = 0; for (uint32_t i = 0; i < len; i++) { @@ -18,20 +18,20 @@ uint32_t delta_adler32(const void *data, uint32_t len) { return (s2 << 16) | s1; } -uint32_t delta_xxhash32(const void *data, uint32_t len) { +uint32_t delta_xxhash32(const void* data, uint32_t len) { return XXH32(data, len, 0); } -DeltaSignature *delta_signature_create(const void *old_file_data, - uint64_t old_file_size, - uint32_t block_size) { +DeltaSignature* delta_signature_create(const void* old_file_data, uint64_t old_file_size, + uint32_t block_size) { if (old_file_data == NULL || old_file_size == 0 || block_size == 0) return NULL; uint32_t block_count = (uint32_t)((old_file_size + block_size - 1) / block_size); - DeltaSignature *sig = malloc(sizeof(DeltaSignature)); - if (!sig) return NULL; + DeltaSignature* sig = malloc(sizeof(DeltaSignature)); + if (!sig) + return NULL; sig->file_size = old_file_size; sig->block_size = block_size; @@ -42,12 +42,11 @@ DeltaSignature *delta_signature_create(const void *old_file_data, return NULL; } - const uint8_t *data = (const uint8_t *)old_file_data; + const uint8_t* data = (const uint8_t*)old_file_data; for (uint32_t i = 0; i < block_count; i++) { uint64_t offset = (uint64_t)i * block_size; - uint32_t len = (uint32_t)((old_file_size - offset < block_size) - ? (old_file_size - offset) - : block_size); + uint32_t len = + (uint32_t)((old_file_size - offset < block_size) ? (old_file_size - offset) : block_size); sig->blocks[i].adler32 = delta_adler32(data + offset, len); sig->blocks[i].xxhash = delta_xxhash32(data + offset, len); } @@ -55,14 +54,16 @@ DeltaSignature *delta_signature_create(const void *old_file_data, return sig; } -Data *delta_signature_serialize(const DeltaSignature *sig) { - if (!sig) return NULL; +Data* delta_signature_serialize(const DeltaSignature* sig) { + if (!sig) + return NULL; uint64_t total = sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint32_t) + (uint64_t)sig->block_count * (sizeof(uint32_t) + sizeof(uint32_t)); - uint8_t *buf = malloc((size_t)total); - if (!buf) return NULL; + uint8_t* buf = malloc((size_t)total); + if (!buf) + return NULL; size_t pos = 0; memcpy(buf + pos, &sig->file_size, sizeof(uint64_t)); @@ -82,15 +83,16 @@ Data *delta_signature_serialize(const DeltaSignature *sig) { return data_create(buf, (size_t)total); } -DeltaSignature *delta_signature_deserialize(const Data *data) { +DeltaSignature* delta_signature_deserialize(const Data* data) { if (!data || data->size < sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint32_t)) return NULL; - const uint8_t *buf = (const uint8_t *)data->data; + const uint8_t* buf = (const uint8_t*)data->data; size_t pos = 0; - DeltaSignature *sig = malloc(sizeof(DeltaSignature)); - if (!sig) return NULL; + DeltaSignature* sig = malloc(sizeof(DeltaSignature)); + if (!sig) + return NULL; memcpy(&sig->file_size, buf + pos, sizeof(uint64_t)); pos += sizeof(uint64_t); @@ -122,31 +124,35 @@ DeltaSignature *delta_signature_deserialize(const Data *data) { return sig; } -void delta_signature_destroy(DeltaSignature *sig) { - if (!sig) return; +void delta_signature_destroy(DeltaSignature* sig) { + if (!sig) + return; free(sig->blocks); free(sig); } -static bool ensure_capacity(DeltaInstruction **instrs, uint32_t *capacity, - uint32_t count) { - if (count < *capacity) return true; +static bool ensure_capacity(DeltaInstruction** instrs, uint32_t* capacity, uint32_t count) { + if (count < *capacity) + return true; uint32_t new_cap = *capacity * 2; - DeltaInstruction *tmp = realloc(*instrs, new_cap * sizeof(DeltaInstruction)); - if (!tmp) return false; + DeltaInstruction* tmp = realloc(*instrs, new_cap * sizeof(DeltaInstruction)); + if (!tmp) + return false; *instrs = tmp; *capacity = new_cap; return true; } -static bool flush_literal(DeltaInstruction **instrs, uint32_t *capacity, - uint32_t *count, const uint8_t *data, - uint64_t start, uint64_t end) { - if (start >= end) return true; +static bool flush_literal(DeltaInstruction** instrs, uint32_t* capacity, uint32_t* count, + const uint8_t* data, uint64_t start, uint64_t end) { + if (start >= end) + return true; uint32_t lit_len = (uint32_t)(end - start); - if (!ensure_capacity(instrs, capacity, *count)) return false; - uint8_t *lit_data = malloc(lit_len); - if (!lit_data) return false; + if (!ensure_capacity(instrs, capacity, *count)) + return false; + uint8_t* lit_data = malloc(lit_len); + if (!lit_data) + return false; memcpy(lit_data, data + start, lit_len); (*instrs)[*count].type = DELTA_INSTR_LITERAL; (*instrs)[*count].literal.data = lit_data; @@ -155,17 +161,18 @@ static bool flush_literal(DeltaInstruction **instrs, uint32_t *capacity, return true; } -Delta *delta_compute(const void *new_file_data, uint64_t new_file_size, - const DeltaSignature *sig, uint32_t block_size) { +Delta* delta_compute(const void* new_file_data, uint64_t new_file_size, const DeltaSignature* sig, + uint32_t block_size) { if (!new_file_data || !sig || new_file_size == 0 || block_size == 0) return NULL; - const uint8_t *new_data = (const uint8_t *)new_file_data; + const uint8_t* new_data = (const uint8_t*)new_file_data; uint32_t capacity = 64; uint32_t count = 0; - DeltaInstruction *instrs = malloc(capacity * sizeof(DeltaInstruction)); - if (!instrs) return NULL; + DeltaInstruction* instrs = malloc(capacity * sizeof(DeltaInstruction)); + if (!instrs) + return NULL; uint64_t literal_start = 0; bool has_literal = false; @@ -176,20 +183,17 @@ Delta *delta_compute(const void *new_file_data, uint64_t new_file_size, bool rolling_valid = false; while (i < new_file_size) { - uint32_t window_len = (uint32_t)((new_file_size - i < block_size) - ? (new_file_size - i) - : block_size); + uint32_t window_len = + (uint32_t)((new_file_size - i < block_size) ? (new_file_size - i) : block_size); bool full_window = (window_len == block_size); uint32_t adler; if (rolling_valid && full_window) { uint8_t old_byte = new_data[i - 1]; uint8_t new_byte = new_data[i + block_size - 1]; - s1 = (s1 + DELTA_ADLER32_MODULUS - old_byte + new_byte) % - DELTA_ADLER32_MODULUS; + s1 = (s1 + DELTA_ADLER32_MODULUS - old_byte + new_byte) % DELTA_ADLER32_MODULUS; s2 = (s2 + DELTA_ADLER32_MODULUS - - (uint32_t)((uint64_t)block_size * old_byte % DELTA_ADLER32_MODULUS) + - s1 - 1) % + (uint32_t)((uint64_t)block_size * old_byte % DELTA_ADLER32_MODULUS) + s1 - 1) % DELTA_ADLER32_MODULUS; adler = (s2 << 16) | s1; } else { @@ -209,8 +213,7 @@ Delta *delta_compute(const void *new_file_data, uint64_t new_file_size, uint32_t xxh = delta_xxhash32(new_data + i, window_len); if (xxh == sig->blocks[j].xxhash) { if (has_literal) { - if (!flush_literal(&instrs, &capacity, &count, new_data, - literal_start, i)) { + if (!flush_literal(&instrs, &capacity, &count, new_data, literal_start, i)) { free(instrs); return NULL; } @@ -245,14 +248,13 @@ Delta *delta_compute(const void *new_file_data, uint64_t new_file_size, } if (has_literal) { - if (!flush_literal(&instrs, &capacity, &count, new_data, - literal_start, new_file_size)) { + if (!flush_literal(&instrs, &capacity, &count, new_data, literal_start, new_file_size)) { free(instrs); return NULL; } } - Delta *delta = malloc(sizeof(Delta)); + Delta* delta = malloc(sizeof(Delta)); if (!delta) { for (uint32_t k = 0; k < count; k++) { if (instrs[k].type == DELTA_INSTR_LITERAL) @@ -279,12 +281,14 @@ Delta *delta_compute(const void *new_file_data, uint64_t new_file_size, return delta; } -Data *delta_serialize(const Delta *delta) { - if (!delta) return NULL; +Data* delta_serialize(const Delta* delta) { + if (!delta) + return NULL; uint64_t total = sizeof(uint64_t) + sizeof(uint32_t) + delta->delta_size; - uint8_t *buf = malloc((size_t)total); - if (!buf) return NULL; + uint8_t* buf = malloc((size_t)total); + if (!buf) + return NULL; size_t pos = 0; memcpy(buf + pos, &delta->new_file_size, sizeof(uint64_t)); @@ -307,8 +311,7 @@ Data *delta_serialize(const Delta *delta) { } else { memcpy(buf + pos, &delta->instructions[i].literal.length, sizeof(uint32_t)); pos += sizeof(uint32_t); - memcpy(buf + pos, delta->instructions[i].literal.data, - delta->instructions[i].literal.length); + memcpy(buf + pos, delta->instructions[i].literal.data, delta->instructions[i].literal.length); pos += delta->instructions[i].literal.length; } } @@ -316,15 +319,16 @@ Data *delta_serialize(const Delta *delta) { return data_create(buf, (size_t)total); } -Delta *delta_deserialize(const Data *data) { +Delta* delta_deserialize(const Data* data) { if (!data || data->size < sizeof(uint64_t) + sizeof(uint32_t)) return NULL; - const uint8_t *buf = (const uint8_t *)data->data; + const uint8_t* buf = (const uint8_t*)data->data; size_t pos = 0; - Delta *delta = malloc(sizeof(Delta)); - if (!delta) return NULL; + Delta* delta = malloc(sizeof(Delta)); + if (!delta) + return NULL; memcpy(&delta->new_file_size, buf + pos, sizeof(uint64_t)); pos += sizeof(uint64_t); @@ -408,21 +412,22 @@ Delta *delta_deserialize(const Data *data) { return delta; } -void *delta_apply(const void *old_data, uint64_t old_size, const Delta *delta, +void* delta_apply(const void* old_data, uint64_t old_size, const Delta* delta, uint32_t block_size) { - if (!old_data || !delta) return NULL; + if (!old_data || !delta) + return NULL; - void *output = malloc((size_t)delta->new_file_size); - if (!output) return NULL; + void* output = malloc((size_t)delta->new_file_size); + if (!output) + return NULL; - uint8_t *out = (uint8_t *)output; - uint8_t *old = (uint8_t *)old_data; + uint8_t* out = (uint8_t*)output; + uint8_t* old = (uint8_t*)old_data; uint64_t out_pos = 0; for (uint32_t i = 0; i < delta->instruction_count; i++) { if (delta->instructions[i].type == DELTA_INSTR_BLOCK_MATCH) { - uint64_t src_offset = (uint64_t)delta->instructions[i].match.block_index * - block_size; + uint64_t src_offset = (uint64_t)delta->instructions[i].match.block_index * block_size; src_offset += delta->instructions[i].match.block_offset; uint32_t len = delta->instructions[i].match.length; @@ -447,8 +452,9 @@ void *delta_apply(const void *old_data, uint64_t old_size, const Delta *delta, return output; } -void delta_destroy(Delta *delta) { - if (!delta) return; +void delta_destroy(Delta* delta) { + if (!delta) + return; for (uint32_t i = 0; i < delta->instruction_count; i++) { if (delta->instructions[i].type == DELTA_INSTR_LITERAL) free(delta->instructions[i].literal.data); @@ -469,8 +475,9 @@ bool delta_should_attempt(uint64_t old_size, uint64_t new_size, uint64_t max_fil return true; } -bool delta_is_worthwhile(const Delta *delta, uint64_t new_file_size) { - if (!delta || delta->instruction_count == 0) return false; +bool delta_is_worthwhile(const Delta* delta, uint64_t new_file_size) { + if (!delta || delta->instruction_count == 0) + return false; bool has_match = false; for (uint32_t i = 0; i < delta->instruction_count; i++) { @@ -479,7 +486,8 @@ bool delta_is_worthwhile(const Delta *delta, uint64_t new_file_size) { break; } } - if (!has_match) return false; + if (!has_match) + return false; double ratio = (double)delta->delta_size / (double)new_file_size; return ratio < DELTA_FALLBACK_RATIO; diff --git a/src/shared/delta.h b/src/shared/delta.h index 209162d..96cf0a6 100644 --- a/src/shared/delta.h +++ b/src/shared/delta.h @@ -6,17 +6,17 @@ #include #include -#define DELTA_BLOCK_SIZE_DEFAULT 8192U -#define DELTA_BLOCK_SIZE_MIN 1024U -#define DELTA_BLOCK_SIZE_MAX 65536U -#define DELTA_MIN_FILE_SIZE 16384ULL -#define DELTA_MAX_FILE_SIZE (256ULL * 1024 * 1024) -#define DELTA_MAX_SIZE_RATIO 10.0 -#define DELTA_FALLBACK_RATIO 0.7 -#define DELTA_ADLER32_MODULUS 65521U +#define DELTA_BLOCK_SIZE_DEFAULT 8192U +#define DELTA_BLOCK_SIZE_MIN 1024U +#define DELTA_BLOCK_SIZE_MAX 65536U +#define DELTA_MIN_FILE_SIZE 16384ULL +#define DELTA_MAX_FILE_SIZE (256ULL * 1024 * 1024) +#define DELTA_MAX_SIZE_RATIO 10.0 +#define DELTA_FALLBACK_RATIO 0.7 +#define DELTA_ADLER32_MODULUS 65521U -#define DELTA_OP_BLOCK_MATCH 0x01 -#define DELTA_OP_LITERAL 0x02 +#define DELTA_OP_BLOCK_MATCH 0x01 +#define DELTA_OP_LITERAL 0x02 typedef struct { uint32_t adler32; @@ -27,13 +27,10 @@ typedef struct { uint64_t file_size; uint32_t block_size; uint32_t block_count; - DeltaBlockSig *blocks; + DeltaBlockSig* blocks; } DeltaSignature; -typedef enum { - DELTA_INSTR_BLOCK_MATCH = 0x01, - DELTA_INSTR_LITERAL = 0x02 -} DeltaInstrType; +typedef enum { DELTA_INSTR_BLOCK_MATCH = 0x01, DELTA_INSTR_LITERAL = 0x02 } DeltaInstrType; typedef struct { DeltaInstrType type; @@ -44,7 +41,7 @@ typedef struct { uint32_t length; } match; struct { - uint8_t *data; + uint8_t* data; uint32_t length; } literal; }; @@ -53,29 +50,27 @@ typedef struct { typedef struct { uint64_t new_file_size; uint32_t instruction_count; - DeltaInstruction *instructions; + DeltaInstruction* instructions; uint64_t delta_size; } Delta; -DeltaSignature *delta_signature_create(const void *old_file_data, - uint64_t old_file_size, - uint32_t block_size); -Data *delta_signature_serialize(const DeltaSignature *sig); -DeltaSignature *delta_signature_deserialize(const Data *data); -void delta_signature_destroy(DeltaSignature *sig); +DeltaSignature* delta_signature_create(const void* old_file_data, uint64_t old_file_size, + uint32_t block_size); +Data* delta_signature_serialize(const DeltaSignature* sig); +DeltaSignature* delta_signature_deserialize(const Data* data); +void delta_signature_destroy(DeltaSignature* sig); -Delta *delta_compute(const void *new_file_data, uint64_t new_file_size, - const DeltaSignature *sig, uint32_t block_size); -Data *delta_serialize(const Delta *delta); -Delta *delta_deserialize(const Data *data); -void *delta_apply(const void *old_data, uint64_t old_size, const Delta *delta, - uint32_t block_size); -void delta_destroy(Delta *delta); +Delta* delta_compute(const void* new_file_data, uint64_t new_file_size, const DeltaSignature* sig, + uint32_t block_size); +Data* delta_serialize(const Delta* delta); +Delta* delta_deserialize(const Data* data); +void* delta_apply(const void* old_data, uint64_t old_size, const Delta* delta, uint32_t block_size); +void delta_destroy(Delta* delta); bool delta_should_attempt(uint64_t old_size, uint64_t new_size, uint64_t max_file_size); -bool delta_is_worthwhile(const Delta *delta, uint64_t new_file_size); +bool delta_is_worthwhile(const Delta* delta, uint64_t new_file_size); -uint32_t delta_adler32(const void *data, uint32_t len); -uint32_t delta_xxhash32(const void *data, uint32_t len); +uint32_t delta_adler32(const void* data, uint32_t len); +uint32_t delta_xxhash32(const void* data, uint32_t len); #endif diff --git a/src/shared/file.c b/src/shared/file.c index 6eeabf5..0fb81ff 100644 --- a/src/shared/file.c +++ b/src/shared/file.c @@ -137,33 +137,50 @@ bool file_save_to_disk(const char* root_directory, File* file) { return ok; } -static void *old_data_from_path(const char *full_path, unsigned long long old_size) { - void *data = malloc((size_t)old_size); - if (!data) return NULL; - FILE *fp = fopen(full_path, "rb"); - if (!fp) { free(data); return NULL; } +static void* old_data_from_path(const char* full_path, unsigned long long old_size) { + void* data = malloc((size_t)old_size); + if (!data) + return NULL; + FILE* fp = fopen(full_path, "rb"); + if (!fp) { + free(data); + return NULL; + } size_t nread = fread(data, 1, (size_t)old_size, fp); fclose(fp); - if (nread != (size_t)old_size) { free(data); return NULL; } + if (nread != (size_t)old_size) { + free(data); + return NULL; + } return data; } -static File *receive_delta_file(int fd, const Config *config, const char *check_path, - void *old_data, unsigned long long old_size) { - if (!old_data) return NULL; +static File* receive_delta_file(int fd, const Config* config, const char* check_path, + void* old_data, unsigned long long old_size) { + if (!old_data) + return NULL; - DeltaSignature *sig = delta_signature_create(old_data, old_size, - config->delta_block_size); - if (!sig) { free(old_data); return NULL; } + DeltaSignature* sig = delta_signature_create(old_data, old_size, config->delta_block_size); + if (!sig) { + free(old_data); + return NULL; + } - Data *sig_data = delta_signature_serialize(sig); - if (!sig_data) { delta_signature_destroy(sig); free(old_data); return NULL; } + Data* sig_data = delta_signature_serialize(sig); + if (!sig_data) { + delta_signature_destroy(sig); + free(old_data); + return NULL; + } - bool sig_sent = send_status(fd, STATUS_DELTA_SIGNATURE) && - send_data(fd, sig_data); + bool sig_sent = send_status(fd, STATUS_DELTA_SIGNATURE) && send_data(fd, sig_data); data_destroy(sig_data); - if (!sig_sent) { delta_signature_destroy(sig); free(old_data); return NULL; } + if (!sig_sent) { + delta_signature_destroy(sig); + free(old_data); + return NULL; + } Status resp; if (!receive_status(fd, &resp)) { @@ -173,7 +190,7 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ } if (resp == STATUS_DELTA_DATA) { - Data *delta_data = receive_data(fd); + Data* delta_data = receive_data(fd); if (!delta_data) { delta_signature_destroy(sig); free(old_data); @@ -181,7 +198,7 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ return NULL; } - Data *raw_delta = delta_data; + Data* raw_delta = delta_data; if (config->use_compression) { raw_delta = data_decompress(delta_data); data_destroy(delta_data); @@ -193,7 +210,7 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ } } - Delta *delta = delta_deserialize(raw_delta); + Delta* delta = delta_deserialize(raw_delta); data_destroy(raw_delta); if (!delta) { free(old_data); @@ -202,8 +219,7 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ return NULL; } - void *new_data = delta_apply(old_data, old_size, delta, - config->delta_block_size); + void* new_data = delta_apply(old_data, old_size, delta, config->delta_block_size); uint64_t new_size = delta->new_file_size; delta_destroy(delta); @@ -214,7 +230,7 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ return NULL; } - File *file = file_create(check_path); + File* file = file_create(check_path); if (!file) { free(new_data); free(old_data); @@ -248,16 +264,23 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ delta_signature_destroy(sig); free(old_data); - File *file = file_create(check_path); - if (!file) { send_status(fd, STATUS_ERROR); return NULL; } + File* file = file_create(check_path); + if (!file) { + send_status(fd, STATUS_ERROR); + return NULL; + } if (config->use_metadata) { int meta_ok = 1; file->metadata = metadata_receive(fd, &meta_ok); - if (!meta_ok) { file_destroy(file); send_status(fd, STATUS_ERROR); return NULL; } + if (!meta_ok) { + file_destroy(file); + send_status(fd, STATUS_ERROR); + return NULL; + } } - Data *file_data = receive_data(fd); + Data* file_data = receive_data(fd); if (file_data == NULL) { file_destroy(file); send_status(fd, STATUS_ERROR); @@ -265,9 +288,13 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ } if (config->use_compression) { - Data *uncompressed = data_decompress(file_data); + Data* uncompressed = data_decompress(file_data); data_destroy(file_data); - if (uncompressed == NULL) { file_destroy(file); send_status(fd, STATUS_ERROR); return NULL; } + if (uncompressed == NULL) { + file_destroy(file); + send_status(fd, STATUS_ERROR); + return NULL; + } file_data = uncompressed; } @@ -284,7 +311,10 @@ static File *receive_delta_file(int fd, const Config *config, const char *check_ File* receive_incremental_check(int fd, const Config* config, bool* skipped) { *skipped = false; char* check_path = receive_str(fd); - if (check_path == NULL) { send_status(fd, STATUS_ERROR); return NULL; } + if (check_path == NULL) { + send_status(fd, STATUS_ERROR); + return NULL; + } unsigned long long check_size; long long check_mtime; @@ -300,12 +330,15 @@ File* receive_incremental_check(int fd, const Config* config, bool* skipped) { bool has_old_file = (full_path && stat(full_path, &st) == 0); unsigned long long old_size = has_old_file ? (unsigned long long)st.st_size : 0; - bool match = has_old_file && - (unsigned long long)st.st_size == check_size && + bool match = has_old_file && (unsigned long long)st.st_size == check_size && (long long)st.st_mtime == check_mtime; if (match) { - if (!send_status(fd, STATUS_OK)) { free(full_path); free(check_path); return NULL; } + if (!send_status(fd, STATUS_OK)) { + free(full_path); + free(check_path); + return NULL; + } free(full_path); free(check_path); *skipped = true; @@ -316,9 +349,8 @@ File* receive_incremental_check(int fd, const Config* config, bool* skipped) { delta_should_attempt(old_size, check_size, config->delta_max_file_size); if (try_delta) { - void *old_data = old_data_from_path(full_path, old_size); - File *delta_file = receive_delta_file(fd, config, check_path, - old_data, old_size); + void* old_data = old_data_from_path(full_path, old_size); + File* delta_file = receive_delta_file(fd, config, check_path, old_data, old_size); if (delta_file) { free(full_path); free(check_path); @@ -338,7 +370,10 @@ File* receive_incremental_check(int fd, const Config* config, bool* skipped) { File* file = file_create(check_path); free(check_path); free(full_path); - if (file == NULL) { send_status(fd, STATUS_ERROR); return NULL; } + if (file == NULL) { + send_status(fd, STATUS_ERROR); + return NULL; + } if (config->use_metadata) { int meta_ok = 1; @@ -398,10 +433,13 @@ bool to_disk(const char* path, const void* data, unsigned long long data_size) { return true; } -bool file_send_sendfile(File *file, int file_descriptor, bool use_metadata, int compression_level, bool send_path) { +bool file_send_sendfile(File* file, int file_descriptor, bool use_metadata, int compression_level, + bool send_path) { (void)compression_level; - if (send_path && !send_str(file_descriptor, file->path)) return false; - if (use_metadata && !metadata_send(file_descriptor, file->metadata)) return false; + if (send_path && !send_str(file_descriptor, file->path)) + return false; + if (use_metadata && !metadata_send(file_descriptor, file->metadata)) + return false; int fd = open(file->path, O_RDONLY); if (fd == -1) { diff --git a/src/shared/file.h b/src/shared/file.h index 60e799c..f6acac2 100644 --- a/src/shared/file.h +++ b/src/shared/file.h @@ -26,8 +26,8 @@ bool file_load_data(File* file); File* file_receive(const Config* config, int file_descriptor); bool file_send_single_calls(File* file, int file_descriptor, bool use_metadata, int compression_level, bool send_path); -bool file_send_sendfile(File* file, int file_descriptor, bool use_metadata, - int compression_level, bool send_path); +bool file_send_sendfile(File* file, int file_descriptor, bool use_metadata, int compression_level, + bool send_path); size_t file_content_to_buffer(File* file); FileMetadata* file_metadata_create(const struct stat* stats); void file_metadata_destroy(void* metadata); diff --git a/tests/test_delta.c b/tests/test_delta.c index 4fbbe26..75932ec 100644 --- a/tests/test_delta.c +++ b/tests/test_delta.c @@ -4,7 +4,7 @@ #include static void test_adler32_basic() { - const char *data = "Hello"; + const char* data = "Hello"; uint32_t h = delta_adler32(data, 5); EXPECT_TRUE(h != 0); uint32_t h2 = delta_adler32(data, 5); @@ -12,15 +12,15 @@ static void test_adler32_basic() { } static void test_adler32_different_data() { - const char *a = "AAAA"; - const char *b = "BBBB"; + const char* a = "AAAA"; + const char* b = "BBBB"; uint32_t ha = delta_adler32(a, 4); uint32_t hb = delta_adler32(b, 4); EXPECT_TRUE(ha != hb); } static void test_xxhash32_basic() { - const char *data = "Hello"; + const char* data = "Hello"; uint32_t h = delta_xxhash32(data, 5); EXPECT_TRUE(h != 0); uint32_t h2 = delta_xxhash32(data, 5); @@ -28,8 +28,8 @@ static void test_xxhash32_basic() { } static void test_xxhash32_different_data() { - const char *a = "AAAA"; - const char *b = "BBBB"; + const char* a = "AAAA"; + const char* b = "BBBB"; uint32_t ha = delta_xxhash32(a, 4); uint32_t hb = delta_xxhash32(b, 4); EXPECT_TRUE(ha != hb); @@ -37,17 +37,18 @@ static void test_xxhash32_different_data() { static void test_signature_roundtrip() { char old_data[4096]; - for (int i = 0; i < 4096; i++) old_data[i] = (char)(i % 256); + for (int i = 0; i < 4096; i++) + old_data[i] = (char)(i % 256); - DeltaSignature *sig = delta_signature_create(old_data, 4096, 1024); + DeltaSignature* sig = delta_signature_create(old_data, 4096, 1024); EXPECT_NOT_NULL(sig); EXPECT_EQ_INT((int)sig->block_count, 4); EXPECT_EQ_INT((int)sig->block_size, 1024); - Data *serialized = delta_signature_serialize(sig); + Data* serialized = delta_signature_serialize(sig); EXPECT_NOT_NULL(serialized); - DeltaSignature *deserialized = delta_signature_deserialize(serialized); + DeltaSignature* deserialized = delta_signature_deserialize(serialized); EXPECT_NOT_NULL(deserialized); EXPECT_EQ_INT((int)deserialized->block_count, (int)sig->block_count); EXPECT_EQ_INT((int)deserialized->block_size, (int)sig->block_size); @@ -64,12 +65,13 @@ static void test_signature_roundtrip() { static void test_delta_identical_files() { char data[2048]; - for (int i = 0; i < 2048; i++) data[i] = (char)(i % 128); + for (int i = 0; i < 2048; i++) + data[i] = (char)(i % 128); - DeltaSignature *sig = delta_signature_create(data, 2048, 512); + DeltaSignature* sig = delta_signature_create(data, 2048, 512); EXPECT_NOT_NULL(sig); - Delta *delta = delta_compute(data, 2048, sig, 512); + Delta* delta = delta_compute(data, 2048, sig, 512); EXPECT_NOT_NULL(delta); bool has_match = false; @@ -105,10 +107,10 @@ static void test_delta_small_edit() { new_data[101] = 'Y'; new_data[102] = 'Z'; - DeltaSignature *sig = delta_signature_create(old_data, 4096, 1024); + DeltaSignature* sig = delta_signature_create(old_data, 4096, 1024); EXPECT_NOT_NULL(sig); - Delta *delta = delta_compute(new_data, 4096, sig, 1024); + Delta* delta = delta_compute(new_data, 4096, sig, 1024); EXPECT_NOT_NULL(delta); uint64_t total_literal = 0; @@ -122,7 +124,7 @@ static void test_delta_small_edit() { EXPECT_TRUE(match_count > 0); EXPECT_TRUE(total_literal < 4096); - void *reconstructed = delta_apply(old_data, 4096, delta, 1024); + void* reconstructed = delta_apply(old_data, 4096, delta, 1024); EXPECT_NOT_NULL(reconstructed); EXPECT_EQ_INT(memcmp(reconstructed, new_data, 4096), 0); @@ -139,10 +141,10 @@ static void test_delta_completely_different() { new_data[i] = (char)(i * 13 + 97); } - DeltaSignature *sig = delta_signature_create(old_data, 4096, 1024); + DeltaSignature* sig = delta_signature_create(old_data, 4096, 1024); EXPECT_NOT_NULL(sig); - Delta *delta = delta_compute(new_data, 4096, sig, 1024); + Delta* delta = delta_compute(new_data, 4096, sig, 1024); EXPECT_NOT_NULL(delta); bool has_match = false; @@ -169,19 +171,19 @@ static void test_delta_serialize_roundtrip() { new_data[500] = 'A'; new_data[501] = 'B'; - DeltaSignature *sig = delta_signature_create(old_data, 4096, 1024); - Delta *delta = delta_compute(new_data, 4096, sig, 1024); + DeltaSignature* sig = delta_signature_create(old_data, 4096, 1024); + Delta* delta = delta_compute(new_data, 4096, sig, 1024); EXPECT_NOT_NULL(delta); - Data *serialized = delta_serialize(delta); + Data* serialized = delta_serialize(delta); EXPECT_NOT_NULL(serialized); - Delta *deserialized = delta_deserialize(serialized); + Delta* deserialized = delta_deserialize(serialized); EXPECT_NOT_NULL(deserialized); EXPECT_EQ_INT((int)deserialized->new_file_size, (int)delta->new_file_size); EXPECT_EQ_INT((int)deserialized->instruction_count, (int)delta->instruction_count); - void *reconstructed = delta_apply(old_data, 4096, deserialized, 1024); + void* reconstructed = delta_apply(old_data, 4096, deserialized, 1024); EXPECT_NOT_NULL(reconstructed); EXPECT_EQ_INT(memcmp(reconstructed, new_data, 4096), 0); @@ -195,17 +197,19 @@ static void test_delta_serialize_roundtrip() { static void test_delta_file_growth() { char old_data[2048]; char new_data[3072]; - for (int i = 0; i < 2048; i++) old_data[i] = (char)(i % 256); + for (int i = 0; i < 2048; i++) + old_data[i] = (char)(i % 256); memcpy(new_data, old_data, 2048); - for (int i = 2048; i < 3072; i++) new_data[i] = (char)(i % 256); + for (int i = 2048; i < 3072; i++) + new_data[i] = (char)(i % 256); - DeltaSignature *sig = delta_signature_create(old_data, 2048, 512); + DeltaSignature* sig = delta_signature_create(old_data, 2048, 512); EXPECT_NOT_NULL(sig); - Delta *delta = delta_compute(new_data, 3072, sig, 512); + Delta* delta = delta_compute(new_data, 3072, sig, 512); EXPECT_NOT_NULL(delta); - void *reconstructed = delta_apply(old_data, 2048, delta, 512); + void* reconstructed = delta_apply(old_data, 2048, delta, 512); EXPECT_NOT_NULL(reconstructed); EXPECT_EQ_INT(delta->new_file_size, 3072); EXPECT_EQ_INT(memcmp(reconstructed, new_data, 3072), 0); @@ -218,16 +222,18 @@ static void test_delta_file_growth() { static void test_delta_file_shrink() { char old_data[3072]; char new_data[2048]; - for (int i = 0; i < 3072; i++) old_data[i] = (char)(i % 256); - for (int i = 0; i < 2048; i++) new_data[i] = old_data[i]; + for (int i = 0; i < 3072; i++) + old_data[i] = (char)(i % 256); + for (int i = 0; i < 2048; i++) + new_data[i] = old_data[i]; - DeltaSignature *sig = delta_signature_create(old_data, 3072, 512); + DeltaSignature* sig = delta_signature_create(old_data, 3072, 512); EXPECT_NOT_NULL(sig); - Delta *delta = delta_compute(new_data, 2048, sig, 512); + Delta* delta = delta_compute(new_data, 2048, sig, 512); EXPECT_NOT_NULL(delta); - void *reconstructed = delta_apply(old_data, 3072, delta, 512); + void* reconstructed = delta_apply(old_data, 3072, delta, 512); EXPECT_NOT_NULL(reconstructed); EXPECT_EQ_INT(delta->new_file_size, 2048); EXPECT_EQ_INT(memcmp(reconstructed, new_data, 2048), 0); @@ -273,24 +279,24 @@ static void test_large_file_delta() { uint64_t old_size = 200000; uint64_t new_size = 200000; - void *old_data = malloc((size_t)old_size); - void *new_data = malloc((size_t)new_size); + void* old_data = malloc((size_t)old_size); + void* new_data = malloc((size_t)new_size); EXPECT_TRUE(old_data != NULL && new_data != NULL); for (uint64_t i = 0; i < old_size; i++) - ((uint8_t *)old_data)[i] = (uint8_t)(i % 251); + ((uint8_t*)old_data)[i] = (uint8_t)(i % 251); memcpy(new_data, old_data, (size_t)old_size); uint64_t offset = 100000; uint32_t change_len = 4096; for (uint32_t i = 0; i < change_len; i++) - ((uint8_t *)new_data)[offset + i] = (uint8_t)((i * 7 + 13) % 256); + ((uint8_t*)new_data)[offset + i] = (uint8_t)((i * 7 + 13) % 256); - DeltaSignature *sig = delta_signature_create(old_data, old_size, block_size); + DeltaSignature* sig = delta_signature_create(old_data, old_size, block_size); EXPECT_TRUE(sig != NULL); EXPECT_TRUE(sig->block_count == (uint32_t)((old_size + block_size - 1) / block_size)); - Delta *delta = delta_compute(new_data, new_size, sig, block_size); + Delta* delta = delta_compute(new_data, new_size, sig, block_size); EXPECT_TRUE(delta != NULL); uint64_t total_literal = 0; @@ -304,7 +310,7 @@ static void test_large_file_delta() { EXPECT_TRUE(match_count > 0); EXPECT_TRUE(delta->delta_size < new_size / 2); - void *result = delta_apply(old_data, old_size, delta, block_size); + void* result = delta_apply(old_data, old_size, delta, block_size); EXPECT_TRUE(result != NULL); EXPECT_TRUE(delta->new_file_size == new_size); EXPECT_TRUE(memcmp(result, new_data, (size_t)new_size) == 0);