From b03fa0888407b19e3925dfdfd166e6725619de8a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 19 Jul 2023 11:08:37 +0530 Subject: [PATCH] ... --- kittens/transfer/algorithm.c | 25 +++++++++++++------------ kitty_tests/file_transmission.py | 21 +++++++++++++++++++-- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/kittens/transfer/algorithm.c b/kittens/transfer/algorithm.c index 5310b8d11..0ad8d5992 100644 --- a/kittens/transfer/algorithm.c +++ b/kittens/transfer/algorithm.c @@ -305,16 +305,16 @@ unserialize_op(uint8_t *data, size_t len, Operation *op) { static bool write_block(Patcher *self, uint64_t block_index, PyObject *read, PyObject *write) { - FREE_AFTER_FUNCTION PyObject *pos = PyLong_FromUnsignedLongLong((unsigned long long)(self->rsync.block_size * block_index)); + DECREF_AFTER_FUNCTION PyObject *pos = PyLong_FromUnsignedLongLong((unsigned long long)(self->rsync.block_size * block_index)); if (!pos) return false; - FREE_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(read, pos, self->block_buf_view, NULL); + DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(read, pos, self->block_buf_view, NULL); if (ret == NULL) return false; if (!PyLong_Check(ret)) { PyErr_SetString(PyExc_TypeError, "read callback function did not return an integer"); return false; } size_t n = PyLong_AsSize_t(ret); self->rsync.checksummer.update(self->rsync.checksummer.state, self->block_buf.data, n); - FREE_AFTER_FUNCTION PyObject *view = PyMemoryView_FromMemory((char*)self->block_buf.data, n, PyBUF_READ); + DECREF_AFTER_FUNCTION PyObject *view = PyMemoryView_FromMemory((char*)self->block_buf.data, n, PyBUF_READ); if (!view) return false; - FREE_AFTER_FUNCTION PyObject *wret = PyObject_CallFunctionObjArgs(write, view, NULL); + DECREF_AFTER_FUNCTION PyObject *wret = PyObject_CallFunctionObjArgs(write, view, NULL); if (wret == NULL) return false; return true; } @@ -332,9 +332,9 @@ apply_op(Patcher *self, Operation op, PyObject *read, PyObject *write) { case OpData: { self->total_data_in_delta += op.data.len; self->rsync.checksummer.update(self->rsync.checksummer.state, op.data.buf, op.data.len); - FREE_AFTER_FUNCTION PyObject *view = PyMemoryView_FromMemory((char*)op.data.buf, op.data.len, PyBUF_READ); + DECREF_AFTER_FUNCTION PyObject *view = PyMemoryView_FromMemory((char*)op.data.buf, op.data.len, PyBUF_READ); if (!view) return false; - FREE_AFTER_FUNCTION PyObject *wret = PyObject_CallFunctionObjArgs(write, view, NULL); + DECREF_AFTER_FUNCTION PyObject *wret = PyObject_CallFunctionObjArgs(write, view, NULL); if (!wret) return false; } return true; case OpHash: { @@ -404,6 +404,7 @@ PyTypeObject Patcher_Type = { .tp_methods = Patcher_methods, .tp_new = PyType_GenericNew, .tp_init = Patcher_init, + .tp_getset = Patcher_getsets, }; // }}} Patcher @@ -573,12 +574,12 @@ send_op(Differ *self, Operation *op) { len = 5; break; } - FREE_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)metadata, len, PyBUF_READ); - FREE_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->write, mv, NULL); + DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)metadata, len, PyBUF_READ); + DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->write, mv, NULL); if (ret == NULL) return false; if (op->type == OpData) { - FREE_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)op->data.buf, op->data.len, PyBUF_READ); - FREE_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->write, mv, NULL); + DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)op->data.buf, op->data.len, PyBUF_READ); + DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->write, mv, NULL); if (ret == NULL) return false; } self->written = true; @@ -624,9 +625,9 @@ ensure_idx_valid(Differ *self, size_t idx) { self->data.pos = 0; return ensure_idx_valid(self, distance_from_window_pos); } - FREE_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)self->buf.data + self->buf.len, self->buf.cap - self->buf.len, PyBUF_WRITE); + DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)self->buf.data + self->buf.len, self->buf.cap - self->buf.len, PyBUF_WRITE); if (!mv) return false; - FREE_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->read, mv, NULL); + DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->read, mv, NULL); if (!ret) return false; if (!PyLong_Check(ret)) { PyErr_SetString(PyExc_TypeError, "read callback did not return an integer"); return false; } size_t n = PyLong_AsSize_t(ret); diff --git a/kitty_tests/file_transmission.py b/kitty_tests/file_transmission.py index a10a5bf5b..459bc5f49 100644 --- a/kitty_tests/file_transmission.py +++ b/kitty_tests/file_transmission.py @@ -96,7 +96,7 @@ def run_roundtrip_test(self: 'TestFileTransmission', src_data, changed, num_of_p src = memoryview(src_data) delta = bytearray(0) def read_into(b): - global src + nonlocal src n = min(len(b), len(src)) if n > 0: b[:n] = src[:n] @@ -121,6 +121,7 @@ def run_roundtrip_test(self: 'TestFileTransmission', src_data, changed, num_of_p while delta: p.apply_delta_data(delta[:11], read_at, write_changes) + delta = delta[11:] p.finish_delta_data() self.assertEqual(src_data, bytes(output)) limit = 2 * (p.block_size * num_of_patches) @@ -130,7 +131,23 @@ def run_roundtrip_test(self: 'TestFileTransmission', src_data, changed, num_of_p def test_rsync_roundtrip(self: 'TestFileTransmission') -> None: - pass + block_size = 16 + src_data = generate_data(block_size, 16) + changed, num_of_patches, total_patch_size = patch_data(src_data, "3:patch1", "16:patch2", "130:ptch3", "176:patch4", "222:XXYY") + + run_roundtrip_test(self, src_data, src_data[block_size:], 1, block_size) + run_roundtrip_test(self, src_data, changed, num_of_patches, total_patch_size) + run_roundtrip_test(self, src_data, b'', -1, 0) + run_roundtrip_test(self, src_data, src_data, 0, 0) + run_roundtrip_test(self, src_data, changed[:len(changed)-3], num_of_patches, total_patch_size) + run_roundtrip_test(self, src_data, changed[:37] + changed[81:], num_of_patches, total_patch_size) + + block_size = 13 + src_data = generate_data(block_size, 17, "trailer") + changed, num_of_patches, total_patch_size = patch_data(src_data, "0:patch1", "19:patch2") + run_roundtrip_test(self, src_data, changed, num_of_patches, total_patch_size) + run_roundtrip_test(self, src_data, changed[:len(changed)-3], num_of_patches, total_patch_size) + run_roundtrip_test(self, src_data, changed + b"xyz...", num_of_patches, total_patch_size) class TestFileTransmission(BaseTest):