Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-bitarray for openSUSE:Factory
checked in at 2023-02-11 21:57:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bitarray (Old)
and /work/SRC/openSUSE:Factory/.python-bitarray.new.1848 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-bitarray"
Sat Feb 11 21:57:12 2023 rev:15 rq:1064329 version:2.7.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bitarray/python-bitarray.changes
2023-02-10 14:36:13.786246585 +0100
+++
/work/SRC/openSUSE:Factory/.python-bitarray.new.1848/python-bitarray.changes
2023-02-11 21:57:50.223814417 +0100
@@ -1,0 +2,6 @@
+Fri Feb 10 17:42:13 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 2.7.1:
+ * optimize ``util.sc_encode()``
+
+-------------------------------------------------------------------
Old:
----
bitarray-2.7.0.tar.gz
New:
----
bitarray-2.7.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-bitarray.spec ++++++
--- /var/tmp/diff_new_pack.dr6evN/_old 2023-02-11 21:57:50.575816609 +0100
+++ /var/tmp/diff_new_pack.dr6evN/_new 2023-02-11 21:57:50.583816659 +0100
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-bitarray
-Version: 2.7.0
+Version: 2.7.1
Release: 0
Summary: Efficient Arrays of Booleans
License: Python-2.0
++++++ bitarray-2.7.0.tar.gz -> bitarray-2.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/CHANGE_LOG
new/bitarray-2.7.1/CHANGE_LOG
--- old/bitarray-2.7.0/CHANGE_LOG 2023-02-05 17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/CHANGE_LOG 2023-02-10 16:30:12.000000000 +0100
@@ -1,3 +1,8 @@
+2023-02-10 2.7.1:
+-------------------
+ * optimize `util.sc_encode()`
+
+
2023-02-05 2.7.0:
-------------------
* add `util.sc_encode()` and `util.sc_decode()` for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/README.rst
new/bitarray-2.7.1/README.rst
--- old/bitarray-2.7.0/README.rst 2023-02-05 17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/README.rst 2023-02-10 16:30:12.000000000 +0100
@@ -63,7 +63,7 @@
$ python -c 'import bitarray; bitarray.test()'
bitarray is installed in: /Users/ilan/bitarray/bitarray
- bitarray version: 2.7.0
+ bitarray version: 2.7.1
sys.version: 3.11.0 (main, Oct 25 2022) [Clang 14.0.4]
sys.prefix: /Users/ilan/Mini3/envs/py311
pointer size: 64 bit
@@ -401,7 +401,7 @@
Reference
=========
-bitarray version: 2.7.0 -- `change log
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
+bitarray version: 2.7.1 -- `change log
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
In the following, ``item`` and ``value`` are usually a single bit -
an integer 0 or 1.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/_util.c
new/bitarray-2.7.1/bitarray/_util.c
--- old/bitarray-2.7.0/bitarray/_util.c 2023-02-05 17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/bitarray/_util.c 2023-02-10 16:30:12.000000000 +0100
@@ -32,7 +32,7 @@
return 0;
}
-/* return new bitarray of length 'nbits' (with uninitialized buffer) and
+/* return new bitarray of length `nbits` (with uninitialized buffer) and
endianness given by the PyObject 'endian' */
static bitarrayobject *
new_bitarray(Py_ssize_t nbits, PyObject *endian)
@@ -639,8 +639,8 @@
return 0;
}
-/* Return new reference to bytes object from either str (unicode) or bytes.
- On failure, set exception and return NULL. */
+/* Return new reference to bytes object from either ASCII str (unicode) or
+ bytes. On failure, set exception and return NULL. */
static PyObject *
anystr_to_bytes(PyObject *obj)
{
@@ -669,14 +669,14 @@
{
static char *kwlist[] = {"", "endian", NULL};
PyObject *obj, *bytes, *endian = Py_None;
- bitarrayobject *a = NULL;
+ bitarrayobject *a;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:hex2ba", kwlist,
&obj, &endian))
return NULL;
if ((bytes = anystr_to_bytes(obj)) == NULL)
- goto error;
+ return NULL;
a = new_bitarray(4 * PyBytes_GET_SIZE(bytes), endian);
if (a == NULL)
@@ -688,7 +688,7 @@
Py_DECREF(bytes);
return (PyObject *) a;
error:
- Py_XDECREF(bytes);
+ Py_DECREF(bytes);
Py_XDECREF((PyObject *) a);
return NULL;
}
@@ -854,7 +854,7 @@
{
static char *kwlist[] = {"", "", "endian", NULL};
PyObject *obj, *bytes, *endian = Py_None;
- bitarrayobject *a = NULL;
+ bitarrayobject *a;
int n, m; /* n = 2^m */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iO|O:base2ba", kwlist,
@@ -865,7 +865,7 @@
return NULL;
if ((bytes = anystr_to_bytes(obj)) == NULL)
- goto error;
+ return NULL;
a = new_bitarray(m * PyBytes_GET_SIZE(bytes), endian);
if (a == NULL)
@@ -877,7 +877,7 @@
Py_DECREF(bytes);
return (PyObject *) a;
error:
- Py_XDECREF(bytes);
+ Py_DECREF(bytes);
Py_XDECREF((PyObject *) a);
return NULL;
}
@@ -1030,28 +1030,9 @@
return n;
}
-/* ---------------------- sparse compressed bitarray ------------------- */
-
-/* Bitarray buffer size (in bytes) that can be indexed by n bytes. E.g.:
- with 1 byte you can index 256 bits which have a buffer size of 32 bytes,
- so BSI(1) = 32, BSI(2) = 8192, ... */
-#define BSI(n) (((Py_ssize_t) 1) << (8 * (n) - 3))
-
-static int
-sc_encode_header(char *str, bitarrayobject *a)
-{
- int len;
-
- len = byte_length(a->nbits);
- *str = (IS_BE(a) ? 0x10 : 0x00) | ((char) len);
- write_n(str + 1, len, a->nbits);
-
- return 1 + len;
-}
-
-/* starting at byte index 'i' count the remaining bits */
+/* starting from byte i count the remaining population in bitarray buffer */
static Py_ssize_t
-count_final(bitarrayobject *a, Py_ssize_t i)
+count_from(bitarrayobject *a, Py_ssize_t i)
{
Py_ssize_t cnt = 0;
@@ -1064,12 +1045,21 @@
return cnt;
}
-/* segment size in bytes - although of little practical value, the code
+/* ---------------------- sparse compressed bitarray -------------------
+ *
+ * see also: doc/sparse_compression.rst
+ */
+
+/* Bitarray buffer size (in bytes) that can be indexed by n bytes. E.g.:
+ with 1 byte you can index 256 bits which have a buffer size of 32 bytes.
+ BSI(1) = 32, BSI(2) = 8_192, BSI(3) = 2_097_152, BSI(4) = 536_870_912 */
+#define BSI(n) (((Py_ssize_t) 1) << (8 * (n) - 3))
+
+/* segment size in bytes - Although of little practical value, the code
below will also work when changing SEGSIZE to 1, 2, 4, 8 or 16, as long
as a multiple of SEGSIZE is 32. The size 32 is rooted in the fact that
a bitarray of 32 bytes (256 bits) can be indexed with one index byte
- (BSI(0) = 32). Our entire 'sc' format is constructed around this.
- */
+ (BSI(1) = 32). Our entire 'sc' format is constructed around this. */
#define SEGSIZE 32
/* number of 256 bit segments given nbits */
@@ -1079,44 +1069,44 @@
Note that we call these "segments", as opposed to "blocks", in order to
avoid confusion with encode blocks.
- 0 1 2 3 4 5 6 index into rts array, i
- +-------+-------+-------+-------+-------+----+
- | 5 | 7 | 0 | 11 | 6 | 4 | count per segment
- +-------+-------+-------+-------+-------+----+
- 0 5 12 12 23 29 33 running totals, rts[i]
-
- In this example we have a bitarray with 6 segments, e.g. with 1407 bits.
- Note that:
-
- * Here we have 6 segments, but the rts array has a size
- of 7 elements: 0 .. 6
- The rts array has always NSEG(nbits) + 1 elements, such that the
- last element is always indexed by NSEG(nbits). Here, NSEG(1407) = 6
-
- * The zeroth element rts[0] is always zero.
-
- * The last last element rts[NSEG(nbits)] is always the total count.
- Here: rts[NSEG(nbits)] = rts[NSEG(1407)] = rts[6] = 33
-
- * The last segment may be partial. Here, spanning 127 bits, that
- is a[1280:1407]. The count of this segment is 4:
- a[1280:].count() = a.count(1, 1280) = 4
-
- * The segment a[512:768] has a count of zero, such that: rts[2] = rts[3]
-
- As each segment covers 256 bits (32 bytes), and each element in the
- running totals array takes up 8 bytes (on a 64-bit machine at least) the
- additional memory to accommodate the rts array is 1/4 of the bitarrays
- memory. However, calculating this array upfront allows count_block() to
+ 0 1 2 3 4 index in rts array, i
+ +-----------+-----------+-----------+-----------+
+ | 5 | 0 | 3 | 4 | segment population
+ | | | | |
+ | [0:256] | [256:512] | [512:768] | [768:987] | bitarray slice
+ +-----------+-----------+-----------+-----------+
+ 0 5 5 8 12 running totals, rts[i]
+
+ In this example we have a bitarray of length nbits = 987. Note that:
+
+ * The number of segments is given by NSEG(nbits).
+ Here we have 4 segments: NSEG(nbits) = NSEG(987) = 4
+
+ * The rts array has always NSEG(nbits) + 1 elements, such that
+ last element is always indexed by NSEG(nbits).
+
+ * The element rts[0] is always zero.
+
+ * The last element rts[NSEG(nbits)] is always the total count.
+ Here: rts[NSEG(nbits)] = rts[NSEG(987)] = rts[4] = 12
+
+ * The last segment may be partial. In that case, it's size it given
+ by nbits % 256. Here: nbits % 256 = 987 % 256 = 219
+
+ As each segment (at large) covers 256 bits (32 bytes), and each element
+ in the running totals array takes up 8 bytes (on a 64-bit machine) the
+ additional memory to accommodate the rts array is therefore 1/4 of the
+ bitarray's memory.
+ However, calculating this array upfront allows sc_count() to
simply look up two entries from the array and take their difference.
- Thus, the speedup we get can be significant.
+ Thus, the speedup is significant.
- The function write_sparse_block() also takes advantage of the running
- totals array, as it can quickly check for segments that only contain
- only zeros to skip.
+ The function sc_write_indices() also takes advantage of the running
+ totals array. It loops over segments and skips to the next segment as
+ soon as the count the current segment is reached.
*/
static Py_ssize_t *
-calc_rts(bitarrayobject *a)
+sc_calc_rts(bitarrayobject *a)
{
const Py_ssize_t n_seg = NSEG(a->nbits); /* number of segments */
const Py_ssize_t c_seg = a->nbits / (8 * SEGSIZE); /* complete segs */
@@ -1125,6 +1115,7 @@
char *buff;
Py_ssize_t *res, i, j;
+ assert(n_seg == c_seg || n_seg == c_seg + 1);
memset(zeros, 0x00, SEGSIZE);
res = (Py_ssize_t *) PyMem_Malloc((size_t)
sizeof(Py_ssize_t) * (n_seg + 1));
@@ -1144,11 +1135,10 @@
res[c_seg] = cnt;
if (n_seg > c_seg) { /* we have a final partial segment */
- assert(n_seg == c_seg + 1);
assert(Py_SIZE(a) <= SEGSIZE * n_seg);
assert(a->nbits && a->nbits < 8 * SEGSIZE * n_seg);
- cnt += count_final(a, SEGSIZE * c_seg);
+ cnt += count_from(a, SEGSIZE * c_seg);
res[n_seg] = cnt;
}
return res;
@@ -1161,7 +1151,7 @@
The offset is required to be multiple of 32 (the segment size), as this
functions makes use of running totals (stored in Py_ssize_t array rts). */
static Py_ssize_t
-count_block(bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset, int n)
+sc_count(bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset, int n)
{
Py_ssize_t nbits;
@@ -1178,8 +1168,7 @@
is 1 << 32. This is problematic, as 32-bit machines can address
at least partially filled type 4 blocks). Therefore, we first
limit BSI(n) by the buffer size before multiplying 8. */
- nbits = Py_MIN(8 * Py_MIN(BSI(n), Py_SIZE(a)),
- a->nbits - 8 * offset);
+ nbits = Py_MIN(8 * Py_MIN(BSI(n), Py_SIZE(a)), a->nbits - 8 * offset);
assert(nbits >= 0);
offset /= SEGSIZE; /* offset in terms of segments now */
@@ -1193,10 +1182,9 @@
buffer str), and return the number of raw bytes.
Note that the encoded block size is the return value + 1. */
static int
-write_raw_block(char *str, bitarrayobject *a, Py_ssize_t *rts,
- Py_ssize_t offset)
+sc_write_raw(char *str, bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset)
{
- Py_ssize_t nbytes = Py_SIZE(a) - offset; /* remaining bytes */
+ const Py_ssize_t nbytes = Py_SIZE(a) - offset; /* remaining bytes */
Py_ssize_t k = Py_MIN(32, nbytes);
assert(nbytes > 0);
@@ -1205,8 +1193,10 @@
raw bytes (otherwise this function wouldn't have been called).
Now also check the next 3 segments. */
while (k < 128 &&
- Py_MIN(32, nbytes - k) <= count_block(a, rts, offset + k, 1))
+ Py_MIN(32, nbytes - k) <= sc_count(a, rts, offset + k, 1))
k += 32;
+
+ assert(k % SEGSIZE == 0);
}
k = Py_MIN(k, nbytes);
assert(0 < k && k <= 128 && k <= nbytes);
@@ -1221,56 +1211,87 @@
return (int) k;
}
-/* Encode one sparse block (from offset, and up to k one bits).
- Return number of bytes written to buffer str (encoded block size). */
+/* Write `k` indices (of `n` bytes each) into buffer `str`.
+ Note that `n` (which is also the block type) has been selected
+ (in sc_encode_block()) such that:
+
+ k = sc_count(a, rts, offset, n) < 256
+*/
+static void
+sc_write_indices(char *str, bitarrayobject *a, Py_ssize_t *rts,
+ Py_ssize_t offset, int n, int k)
+{
+ const char *str_stop = str + n * k; /* stop position in buffer `str` */
+ const char *buff = a->ob_item + offset;
+ Py_ssize_t m, i;
+
+ assert(1 <= n && n <= 4);
+ assert(0 < k && k < 256); /* note that k cannot be 0 in this function */
+ assert(k == sc_count(a, rts, offset, n)); /* see above */
+ assert(offset % SEGSIZE == 0);
+
+ rts += offset / SEGSIZE; /* rts index relative to offset now */
+
+ for (m = 0;;) { /* loop segments */
+ int j, ni;
+
+ assert(m + offset / SEGSIZE < NSEG(a->nbits));
+ ni = (int) (rts[m + 1] - rts[m]); /* indices in this segment */
+ if (ni == 0)
+ goto next_segment;
+
+ for (i = m * SEGSIZE;; i++) { /* loop bytes in segment */
+ assert(i < (m + 1) * SEGSIZE && i + offset < Py_SIZE(a));
+ if (buff[i] == 0)
+ continue;
+
+ for (j = 0; j < 8; j++) /* loop bits */
+ if (buff[i] & BITMASK(a, j)) {
+ write_n(str, n, 8 * i + j);
+ str += n;
+ if (--ni == 0) {
+ /* we have encountered all indices in this segment */
+ if (str == str_stop)
+ return;
+ goto next_segment;
+ }
+ }
+ }
+ next_segment:
+ m++;
+ }
+ Py_UNREACHABLE();
+}
+
+#undef SEGSIZE
+#undef NSEG
+
+/* Write one sparse block (from `offset`, and up to `k` one bits).
+ Return number of bytes written to buffer `str` (encoded block size). */
static Py_ssize_t
-write_sparse_block(char *str, bitarrayobject *a, Py_ssize_t *rts,
- Py_ssize_t offset, int n, int k)
+sc_write_sparse(char *str, bitarrayobject *a, Py_ssize_t *rts,
+ Py_ssize_t offset, int n, int k)
{
- /* bytes to encode limited by remaining buffer size */
- Py_ssize_t na = Py_MIN(BSI(n), Py_SIZE(a) - offset);
- Py_ssize_t i, j, outsize, len = 0;
- char *buff = a->ob_item + offset;
+ int len = 0;
- assert(offset % SEGSIZE == 0);
- assert(1 <= n && n <= 4 && 0 <= k && k < 256);
- assert(na > 0 && offset + na <= Py_SIZE(a));
+ assert(1 <= n && n <= 4);
+ assert(0 <= k && k < 256);
- /* block header */
+ /* write block header */
if (n == 1) { /* type 1 - single byte for each position */
assert(k < 32);
- str[len++] = 0xa0 + k;
+ str[len++] = (char) (0xa0 + k);
}
- else { /* type 2, 3, 4 - multiple bytes for each positions */
- str[len++] = 0xc0 + n;
- str[len++] = k;
+ else { /* type 2, 3, 4 - `n` bytes for each positions */
+ str[len++] = (char) (0xc0 + n);
+ str[len++] = (char) k;
}
if (k == 0) /* no index bytes */
return len;
- /* block data */
- outsize = len + n * k;
- for (i = 0; i < na; i++) {
- if (i % SEGSIZE == 0) {
- j = (i + offset) / SEGSIZE; /* running total index */
- assert(j < NSEG(a->nbits));
- if (rts[j] == rts[j + 1]) { /* the segment has only zeros */
- i += SEGSIZE - 1; /* skip ahead */
- continue;
- }
- }
- assert(offset + i < Py_SIZE(a));
- if (buff[i])
- for (j = 0; j < 8; j++)
- if (buff[i] & BITMASK(a, j)) {
- write_n(str + len, n, 8 * i + j);
- len += n;
- if (len == outsize) /* final index reached */
- return len;
- }
- }
- Py_FatalError("internal sc_encode() error");
- return -1; /* cannot happen - silence compiler warning */
+ /* write block data - `k` indices, `n` bytes per index */
+ sc_write_indices(str + len, a, rts, offset, n, k);
+ return len + n * k;
}
/* Encode one block (starting at offset) and return offset increment.
@@ -1312,15 +1333,15 @@
sc_encode_block(char *str, Py_ssize_t *len,
bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset)
{
- Py_ssize_t nbytes = Py_SIZE(a) - offset; /* remaining bytes */
+ const Py_ssize_t nbytes = Py_SIZE(a) - offset; /* remaining bytes */
int count, n;
assert(nbytes > 0);
- count = (int) count_block(a, rts, offset, 1);
+ count = (int) sc_count(a, rts, offset, 1);
/* are there fewer or equal raw bytes than index bytes */
if (Py_MIN(32, nbytes) <= count) { /* type 0 - raw bytes */
- int k = write_raw_block(str + *len, a, rts, offset);
+ int k = sc_write_raw(str + *len, a, rts, offset);
*len += 1 + k;
return k;
}
@@ -1329,7 +1350,7 @@
Py_ssize_t next_count, size_a, size_b;
/* population for next block type n+1 */
- next_count = count_block(a, rts, offset, n + 1);
+ next_count = sc_count(a, rts, offset, n + 1);
if (next_count >= 256)
/* too many index bytes for next block type n+1 */
break;
@@ -1347,12 +1368,21 @@
count = (int) next_count;
}
- *len += write_sparse_block(str + *len, a, rts, offset, n, count);
+ *len += sc_write_sparse(str + *len, a, rts, offset, n, count);
return BSI(n);
}
-#undef SEGSIZE
-#undef NSEG
+static int
+sc_encode_header(char *str, bitarrayobject *a)
+{
+ int len;
+
+ len = byte_length(a->nbits);
+ *str = (IS_BE(a) ? 0x10 : 0x00) | ((char) len);
+ write_n(str + 1, len, a->nbits);
+
+ return 1 + len;
+}
static PyObject *
sc_encode(PyObject *module, PyObject *obj)
@@ -1361,14 +1391,15 @@
char *str; /* output buffer */
Py_ssize_t len = 0; /* bytes written into output buffer */
bitarrayobject *a;
- Py_ssize_t offset = 0; /* block offset into bitarray a in bytes */
+ Py_ssize_t offset = 0; /* block offset into bitarray `a` in bytes */
Py_ssize_t *rts; /* running totals for 256 bit segments */
if (ensure_bitarray(obj) < 0)
return NULL;
a = (bitarrayobject *) obj;
- if ((rts = calc_rts(a)) == NULL)
+ set_padbits(a);
+ if ((rts = sc_calc_rts(a)) == NULL)
return NULL;
out = PyBytes_FromStringAndSize(NULL, 32768);
@@ -1383,7 +1414,7 @@
/* Make sure we have enough space in output buffer for next block.
The largest block possible is a type 4 block with 255 indices.
- It's site is: 2 header bytes + 4 * 255 index bytes */
+ It's size is: 2 header bytes + 4 * 255 index bytes */
allocated = PyBytes_GET_SIZE(out);
if (allocated < len + 2 + 4 * 255) { /* increase allocation */
if (_PyBytes_Resize(&out, allocated + 32768) < 0)
@@ -1440,10 +1471,10 @@
/* Read k bytes from iter and set elements in bitarray. Return the size of
the offset increment in bytes (i.e. just k), or -1 on failure. */
static Py_ssize_t
-read_raw_block(bitarrayobject *a, Py_ssize_t offset, PyObject *iter, int k)
+sc_read_raw(bitarrayobject *a, Py_ssize_t offset, PyObject *iter, int k)
{
- Py_ssize_t i;
char *buff = a->ob_item + offset;
+ Py_ssize_t i;
if (offset + k > Py_SIZE(a)) {
PyErr_Format(PyExc_ValueError, "decode error (raw): %zd + %d > %zd",
@@ -1463,8 +1494,8 @@
/* Read n * k bytes from iter and set elements in bitarray.
Return size of offset increment in bytes, or -1 on failure. */
static Py_ssize_t
-read_sparse_block(bitarrayobject *a, Py_ssize_t offset, PyObject *iter,
- int n, int k)
+sc_read_sparse(bitarrayobject *a, Py_ssize_t offset, PyObject *iter,
+ int n, int k)
{
assert(1 <= n && n <= 4 && k >= 0);
while (k--) {
@@ -1499,10 +1530,10 @@
return 0;
if (head <= 0x80) /* type 0 - 0x01 .. 0x80 */
- return read_raw_block(a, offset, iter, head);
+ return sc_read_raw(a, offset, iter, head);
if (0xa0 <= head && head < 0xc0) /* type 1 - 0xa0 .. 0xbf */
- return read_sparse_block(a, offset, iter, 1, head - 0xa0);
+ return sc_read_sparse(a, offset, iter, 1, head - 0xa0);
if (0xc2 <= head && head <= 0xc4) { /* type 2 .. 4 - 0xc2 .. 0xc4 */
int k;
@@ -1510,7 +1541,7 @@
if ((k = next_char(iter)) < 0)
return -1;
- return read_sparse_block(a, offset, iter, head - 0xc0, k);
+ return sc_read_sparse(a, offset, iter, head - 0xc0, k);
}
PyErr_Format(PyExc_ValueError, "invalid block head: 0x%02x", head);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/bitarray.h
new/bitarray-2.7.1/bitarray/bitarray.h
--- old/bitarray-2.7.0/bitarray/bitarray.h 2023-02-05 17:58:14.000000000
+0100
+++ new/bitarray-2.7.1/bitarray/bitarray.h 2023-02-10 16:30:12.000000000
+0100
@@ -4,7 +4,7 @@
Author: Ilan Schnell
*/
-#define BITARRAY_VERSION "2.7.0"
+#define BITARRAY_VERSION "2.7.1"
#ifdef STDC_HEADERS
#include <stddef.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/test_bitarray.py
new/bitarray-2.7.1/bitarray/test_bitarray.py
--- old/bitarray-2.7.0/bitarray/test_bitarray.py 2023-02-05
17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/bitarray/test_bitarray.py 2023-02-10
16:30:12.000000000 +0100
@@ -1142,6 +1142,21 @@
a[2:5] = bitarray('0') # remove
self.assertEqual(a, bitarray('11011'))
+ def test_setslice_frozenbitarray(self):
+ a = bitarray('11111111 1111')
+ b = frozenbitarray('0000')
+ a[2:6] = b
+ self.assertEqual(a, bitarray('11000011 1111'))
+ self.assertIsType(b, 'frozenbitarray')
+ self.assertEqual(b, bitarray('0000'))
+
+ b = frozenbitarray('011100')
+ a[::2] = b
+ self.assertEqual(a, bitarray('01101011 0101'))
+ self.check_obj(a)
+ self.assertIsType(b, 'frozenbitarray')
+ self.assertEqual(b, bitarray('011100'))
+
def test_setslice_bitarray_random_same_length(self):
for endian in 'little', 'big':
for _ in range(100):
@@ -2750,22 +2765,6 @@
self.assertRaises(IndexError, a.bytereverse, 5)
self.assertRaises(IndexError, a.bytereverse, 0, 5)
- @skipIf(sys.version_info[0] == 2)
- def test_bytereverse_part(self):
- a = bitarray(5, 'big')
- memoryview(a)[0] = 0x13 # 0001 0011
- self.assertEqual(a, bitarray('0001 0'))
- # the padbits (011) are not treated as zeros
- a.bytereverse()
- self.assertEqual(a, bitarray('1100 1'))
-
- a = bitarray(12, 'little')
- memoryview(a)[1] = 0xd4 # .... .... 0010 1011
- self.assertEqual(a[8:], bitarray('0010'))
- # the padbits (1011) are not treated as zeros
- a.bytereverse(1)
- self.assertEqual(a[8:], bitarray('1101'))
-
def test_bytereverse_byte(self):
for i in range(256):
a = bitarray()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/test_util.py
new/bitarray-2.7.1/bitarray/test_util.py
--- old/bitarray-2.7.0/bitarray/test_util.py 2023-02-05 17:58:14.000000000
+0100
+++ new/bitarray-2.7.1/bitarray/test_util.py 2023-02-10 16:30:12.000000000
+0100
@@ -948,21 +948,22 @@
self.assertEqual(ba2hex(a_be), hex_be)
self.assertEqual(ba2hex(a_le), hex_le)
- def test_round_trip(self):
- s = ''.join(choice(hexdigits) for _ in range(randint(20, 100)))
+ def test_hexdigits(self):
for default_endian in 'big', 'little':
_set_default_endian(default_endian)
- a = hex2ba(s)
- self.check_obj(a)
+ a = hex2ba(hexdigits)
self.assertEqual(len(a) % 4, 0)
self.assertEqual(a.endian(), default_endian)
+ self.assertIsType(a, 'bitarray')
+ self.check_obj(a)
+
t = ba2hex(a)
- self.assertEqual(t, s.lower())
- b = hex2ba(t, default_endian)
- self.assertEQUAL(a, b)
+ self.assertEqual(t, hexdigits.lower())
+ self.assertIsInstance(t, str)
+ self.assertEQUAL(a, hex2ba(t, default_endian))
def test_binascii(self):
- a = urandom(800, 'big')
+ a = urandom(80, 'big')
s = binascii.hexlify(a.tobytes()).decode()
self.assertEqual(ba2hex(a), s)
b = bitarray(endian='big')
@@ -1145,8 +1146,7 @@
(b'\x11\x09\xa1\x08\0', '00000000 1', 'big'),
(b'\x01E\xa3ABD\0', 65 * '0' + '1101', 'little'),
]:
- # the padbits in a frozenbitarray are guaranteed to be zero
- a = frozenbitarray(bits, endian)
+ a = bitarray(bits, endian)
self.assertEqual(sc_encode(a), b)
self.assertEqual(sc_decode(b), a)
@@ -1345,16 +1345,16 @@
for a in bitarray('1', 'big'), frozenbitarray('1', 'big'):
b = sc_encode(a)
self.assertIsInstance(b, bytes)
- self.assertEqual(len(b), 5)
+ self.assertEqual(b, b'\x11\x01\x01\x80\0')
for a in None, [], 0, 123, b'', b'\x00', 3.14:
self.assertRaises(TypeError, sc_encode, a)
def round_trip(self, a):
- b = sc_encode(a)
- c = sc_decode(b)
- self.assertEqual(a, c)
- self.assertEqual(a.endian(), c.endian())
+ c = a.copy()
+ b = sc_decode(sc_encode(a))
+ self.assertTrue(a == b == c)
+ self.assertTrue(a.endian() == b.endian() == c.endian())
def test_encode_zeros(self):
for i in range(18):
@@ -1523,10 +1523,10 @@
self.assertEqual(vl_decode(s), a)
def round_trip(self, a):
+ c = a.copy()
s = vl_encode(a)
b = vl_decode(s)
- self.check_obj(b)
- self.assertEqual(a, b)
+ self.assertTrue(a == b == c)
LEN_PAD_BITS = 3
self.assertEqual(len(s), (len(a) + LEN_PAD_BITS + 6) // 7)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/doc/changelog.rst
new/bitarray-2.7.1/doc/changelog.rst
--- old/bitarray-2.7.0/doc/changelog.rst 2023-02-05 17:58:14.000000000
+0100
+++ new/bitarray-2.7.1/doc/changelog.rst 2023-02-10 16:30:12.000000000
+0100
@@ -1,6 +1,11 @@
Change log
==========
+**2.7.1** (2023-02-10):
+
+* optimize ``util.sc_encode()``
+
+
**2.7.0** (2023-02-05):
* add ``util.sc_encode()`` and ``util.sc_decode()`` for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/doc/reference.rst
new/bitarray-2.7.1/doc/reference.rst
--- old/bitarray-2.7.0/doc/reference.rst 2023-02-05 17:58:14.000000000
+0100
+++ new/bitarray-2.7.1/doc/reference.rst 2023-02-10 16:30:12.000000000
+0100
@@ -1,7 +1,7 @@
Reference
=========
-bitarray version: 2.7.0 -- `change log
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
+bitarray version: 2.7.1 -- `change log
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
In the following, ``item`` and ``value`` are usually a single bit -
an integer 0 or 1.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/bitarray-2.7.0/doc/sparse_compression.rst
new/bitarray-2.7.1/doc/sparse_compression.rst
--- old/bitarray-2.7.0/doc/sparse_compression.rst 2023-02-05
17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/doc/sparse_compression.rst 2023-02-10
16:30:12.000000000 +0100
@@ -48,7 +48,7 @@
compress (ms) decompress (ms) ratio
----------------------------------------------------------
serialize 4.562 1.188 1.0000
- sc 7.864 2.680 0.0158
+ sc 6.069 2.680 0.0158
gzip 920.343 16.161 0.0169
bz2 59.580 33.435 0.0117