fix: address PR review - rolling adler32, extract helpers, configurable max file size
- Fix rolling adler32: add missing -1 in s2 update formula (was producing wrong checksums, causing zero block matches) - Fix file_send_sendfile signature to match typedef (add unused compression_level param) - Extract receive_delta_file() from receive_incremental_check() to reduce nesting depth - Extract send_file_incremental() helper in client_send.c - Add delta_max_file_size to Config, serialized over wire - Add --delta-max CLI flag - Add test_large_file_delta (200KB) and extra delta_should_attempt cases - Remove unused pos_in_block variable from delta_compute
This commit is contained in:
@@ -39,6 +39,7 @@ static void print_usage(void) {
|
||||
printf(" --incremental Skip files unchanged since last transfer\n");
|
||||
printf(" --delta Delta transfer for changed files (requires --incremental)\n");
|
||||
printf(" --delta-block <n> Delta block size in bytes (default: %d)\n", DELTA_BLOCK_SIZE_DEFAULT);
|
||||
printf(" --delta-max <n> 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");
|
||||
@@ -112,6 +113,12 @@ int main(int argc, char *argv[]) {
|
||||
config->delta_block_size = (uint32_t)val;
|
||||
else
|
||||
fprintf(stderr, "Warning: --delta-block value %llu out of range, using default\n", val);
|
||||
} else if (strcmp(argv[i], "--delta-max") == 0 && i + 1 < argc) {
|
||||
unsigned long long val = strtoull(argv[++i], NULL, 10);
|
||||
if (val >= DELTA_MIN_FILE_SIZE)
|
||||
config->delta_max_file_size = val;
|
||||
else
|
||||
fprintf(stderr, "Warning: --delta-max value %llu too small, using default\n", val);
|
||||
} else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "-z") == 0) {
|
||||
config->use_compression = true;
|
||||
log_message(LOG_LEVEL_INFO, "Enabled Compression");
|
||||
|
||||
+31
-32
@@ -87,6 +87,28 @@ static int send_delta(Client *client, File *file, DeltaSignature *sig,
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
|
||||
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;
|
||||
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 == 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;
|
||||
} else {
|
||||
delta_signature_destroy(sig);
|
||||
}
|
||||
if (!send_fn(file, client->file_descriptor, config->use_metadata,
|
||||
config->use_compression ? config->compression_level : 0, false))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int send_chunk(Client *client, Chunk *chunk, Config *config) {
|
||||
if (config->use_chunk_serialization) {
|
||||
if (!send_status(client->file_descriptor, STATUS_CHUNK)) return -1;
|
||||
@@ -102,46 +124,23 @@ int send_chunk(Client *client, Chunk *chunk, Config *config) {
|
||||
} else if (config->use_sendfile && !config->use_compression) {
|
||||
for (int i = 0; i < chunk->element_count; i++) {
|
||||
if (config->use_incremental) {
|
||||
DeltaSignature *sig = NULL;
|
||||
int rc = incremental_check(client, chunk->items[i], &sig);
|
||||
if (rc < 0) { delta_signature_destroy(sig); return -1; }
|
||||
if (rc == 1) { delta_signature_destroy(sig); continue; }
|
||||
if (rc == 2 && config->use_delta) {
|
||||
int drc = send_delta(client, chunk->items[i], sig, config);
|
||||
delta_signature_destroy(sig);
|
||||
if (drc == 0) continue;
|
||||
if (drc < 0) return -1;
|
||||
} else {
|
||||
delta_signature_destroy(sig);
|
||||
}
|
||||
if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata, false))
|
||||
return -1;
|
||||
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;
|
||||
} else {
|
||||
if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1;
|
||||
if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata, true))
|
||||
if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata, 0, true))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < chunk->element_count; i++) {
|
||||
if (config->use_incremental) {
|
||||
DeltaSignature *sig = NULL;
|
||||
int rc = incremental_check(client, chunk->items[i], &sig);
|
||||
if (rc < 0) { delta_signature_destroy(sig); return -1; }
|
||||
if (rc == 1) { delta_signature_destroy(sig); continue; }
|
||||
if (rc == 2 && config->use_delta) {
|
||||
int drc = send_delta(client, chunk->items[i], sig, config);
|
||||
delta_signature_destroy(sig);
|
||||
if (drc == 0) continue;
|
||||
if (drc < 0) return -1;
|
||||
} else {
|
||||
delta_signature_destroy(sig);
|
||||
}
|
||||
if (!file_send_single_calls(chunk->items[i], client->file_descriptor,
|
||||
config->use_metadata,
|
||||
config->use_compression ? config->compression_level : 0,
|
||||
false))
|
||||
return -1;
|
||||
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;
|
||||
} else {
|
||||
if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1;
|
||||
if (!file_send_single_calls(chunk->items[i], client->file_descriptor,
|
||||
|
||||
Reference in New Issue
Block a user