From be833efd3d3be3c618010ab8feb1921db217b574 Mon Sep 17 00:00:00 2001 From: Dusan Klinec Date: Tue, 17 Jan 2017 14:51:57 +0100 Subject: [PATCH 1/3] copy_n: fast copy with memmove fixed - fixed a problem in cases a < b when self == other. Source memory was overwritten. --- bitarray/_bitarray.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/bitarray/_bitarray.c b/bitarray/_bitarray.c index 0add832b1..4a03ff4c9 100644 --- a/bitarray/_bitarray.c +++ b/bitarray/_bitarray.c @@ -254,24 +254,30 @@ copy_n(bitarrayobject *self, idx_t a, assert(0 <= a && a <= self->nbits - n); assert(0 <= b && b <= other->nbits - n); - /* XXX if (self->endian == other->endian && a % 8 == 0 && b % 8 == 0 && n >= 8) { - Py_ssize_t bytes; - idx_t bits; + const Py_ssize_t bytes = (Py_ssize_t) n / 8; + const idx_t bits = bytes * 8; + + if (a <= b){ + memmove(self->ob_item + a / 8, other->ob_item + b / 8, bytes); + } + + if (n != bits) { + copy_n(self, bits + a, other, bits + b, n - bits); + } + + if (a > b){ + memmove(self->ob_item + a / 8, other->ob_item + b / 8, bytes); + } - bytes = n / 8; - bits = 8 * bytes; - copy_n(self, bits + a, other, bits + b, n - bits); - memmove(self->ob_item + a / 8, other->ob_item + b / 8, bytes); return; } - */ /* the different type of looping is only relevant when other and self are the same object, i.e. when copying a piece of an bitarrayobject onto itself */ - if (a < b) { + if (a <= b) { for (i = 0; i < n; i++) /* loop forward (delete) */ setbit(self, i + a, GETBIT(other, i + b)); } From 4e0da30bd04b178cf2545e6e8b08765f10dfa295 Mon Sep 17 00:00:00 2001 From: Dusan Klinec Date: Tue, 17 Jan 2017 14:55:33 +0100 Subject: [PATCH 2/3] copy_n: if n is null return immediately --- bitarray/_bitarray.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bitarray/_bitarray.c b/bitarray/_bitarray.c index 4a03ff4c9..eaaf0d52e 100644 --- a/bitarray/_bitarray.c +++ b/bitarray/_bitarray.c @@ -253,6 +253,9 @@ copy_n(bitarrayobject *self, idx_t a, assert(0 <= n && n <= self->nbits && n <= other->nbits); assert(0 <= a && a <= self->nbits - n); assert(0 <= b && b <= other->nbits - n); + if (n == 0){ + return; + } if (self->endian == other->endian && a % 8 == 0 && b % 8 == 0 && n >= 8) { From f6d8d8dc1e95c8451c35f0e646cd379c2c5aa4e6 Mon Sep 17 00:00:00 2001 From: Dusan Klinec Date: Tue, 17 Jan 2017 14:59:26 +0100 Subject: [PATCH 3/3] randomised tests - more rounds, helped with debugging fast_copy in copy_n --- test/test_bitarray.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_bitarray.py b/test/test_bitarray.py index 4b60e3d6d..27e6ca33f 100644 --- a/test/test_bitarray.py +++ b/test/test_bitarray.py @@ -506,7 +506,7 @@ def test_setitem4(self): for a in self.randombitarrays(): la = len(a) if la == 0: continue - for dum in range(3): + for dum in range(50): step = self.rndsliceidx(la) if step == 0: step = None s = slice(self.rndsliceidx(la), @@ -580,7 +580,7 @@ def test_delitem2(self): for a in self.randombitarrays(): la = len(a) if la == 0: continue - for dum in range(10): + for dum in range(50): step = self.rndsliceidx(la) if step == 0: step = None s = slice(self.rndsliceidx(la),