Skip to content

Commit 0c0c7ea

Browse files
Use hardware accelerated CRC32C function if available (dpkp#1389)
* Use hardware accelerated CRC32C function if available * Add doc notice of optional `crc32c` package
1 parent 92635d9 commit 0c0c7ea

File tree

4 files changed

+28
-5
lines changed

4 files changed

+28
-5
lines changed

docs/install.rst

+13
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,16 @@ Install the `python-snappy` module
7070
.. code:: bash
7171
7272
pip install python-snappy
73+
74+
75+
Optional crc32c install
76+
***********************
77+
Highly recommended if you are using Kafka 11+ brokers. For those `kafka-python`
78+
uses a new message protocol version, that requires calculation of `crc32c`,
79+
which differs from `zlib.crc32` hash implementation. By default `kafka-python`
80+
calculates it in pure python, which is quite slow. To speed it up we optionally
81+
support https://pypi.python.org/pypi/crc32c package if it's installed.
82+
83+
.. code:: bash
84+
85+
pip install crc32c

kafka/record/util.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import binascii
22

33
from kafka.record._crc32c import crc as crc32c_py
4+
try:
5+
from crc32c import crc32 as crc32c_c
6+
except ImportError:
7+
crc32c_c = None
48

59

610
def encode_varint(value, write):
@@ -113,11 +117,15 @@ def decode_varint(buffer, pos=0):
113117
raise ValueError("Out of int64 range")
114118

115119

116-
def calc_crc32c(memview):
120+
_crc32c = crc32c_py
121+
if crc32c_c is not None:
122+
_crc32c = crc32c_c
123+
124+
125+
def calc_crc32c(memview, _crc32c=_crc32c):
117126
""" Calculate CRC-32C (Castagnoli) checksum over a memoryview of data
118127
"""
119-
crc = crc32c_py(memview)
120-
return crc
128+
return _crc32c(memview)
121129

122130

123131
def calc_crc32(memview):

test/record/test_util.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ def test_size_of_varint(encoded, decoded):
6868
assert util.size_of_varint(decoded) == len(encoded)
6969

7070

71-
def test_crc32c():
71+
@pytest.mark.parametrize("crc32_func", [util.crc32c_c, util.crc32c_py])
72+
def test_crc32c(crc32_func):
7273
def make_crc(data):
73-
crc = util.calc_crc32c(data)
74+
crc = crc32_func(data)
7475
return struct.pack(">I", crc)
7576
assert make_crc(b"") == b"\x00\x00\x00\x00"
7677
assert make_crc(b"a") == b"\xc1\xd0\x43\x30"

tox.ini

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ deps =
1818
python-snappy
1919
lz4
2020
xxhash
21+
crc32c
2122
py26: unittest2
2223
commands =
2324
py.test {posargs:--pylint --pylint-rcfile=pylint.rc --pylint-error-types=EF --cov=kafka --cov-config=.covrc}

0 commit comments

Comments
 (0)