diff --git a/mmh3module.cpp b/mmh3module.cpp index d377e0e..45f2dc8 100644 --- a/mmh3module.cpp +++ b/mmh3module.cpp @@ -49,6 +49,28 @@ mmh3_hash(PyObject *self, PyObject *args, PyObject *keywds) #endif } +static PyObject * +mmh3_hash_from_buffer(PyObject *self, PyObject *args, PyObject *keywds) +{ + Py_buffer target_buf; + uint32_t seed = 0; + int32_t result[1]; + + static char *kwlist[] = {(char *)"key", (char *)"seed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, keywds, "s*|I", kwlist, + &target_buf, &seed)) { + return NULL; + } + + MurmurHash3_x86_32(target_buf.buf, target_buf.len, seed, result); +#if PY_MAJOR_VERSION >= 3 + return PyLong_FromLong(result[0]); +#else + return PyInt_FromLong(result[0]); +#endif +} + static PyObject * mmh3_hash64(PyObject *self, PyObject *args, PyObject *keywds) { @@ -151,6 +173,8 @@ static struct module_state _state; static PyMethodDef Mmh3Methods[] = { {"hash", (PyCFunction)mmh3_hash, METH_VARARGS | METH_KEYWORDS, "hash(key[, seed=0]) -> hash value\n Return a 32 bit integer."}, + {"hash_from_buffer", (PyCFunction)mmh3_hash_from_buffer, METH_VARARGS | METH_KEYWORDS, + "hash(key[, seed=0]) -> hash a memory buffer\n Return a 32 bit integer."}, {"hash64", (PyCFunction)mmh3_hash64, METH_VARARGS | METH_KEYWORDS, "hash64(key[, seed=0, x64arch=True]) -> (hash value 1, hash value 2)\n Return a tuple of two 64 bit integers for a string. Optimized for the x64 bit architecture when x64arch=True, otherwise for x86."}, {"hash128", (PyCFunction)mmh3_hash128, METH_VARARGS | METH_KEYWORDS, diff --git a/test_mmh3.py b/test_mmh3.py index a8e4c08..4eb0dc3 100755 --- a/test_mmh3.py +++ b/test_mmh3.py @@ -101,6 +101,10 @@ def test_hash2(): assert mmh3.hash('The quick brown fox jumps over the lazy dog', 0x9747b28c) == u32_to_s32(0x2FA826CD) +def test_hash_from_buffer(): + mview = memoryview('foo'.encode('utf8')) + assert mmh3.hash_from_buffer(mview) == -156908512 + def test_hash_bytes(): assert mmh3.hash_bytes('foo') == b'aE\xf5\x01W\x86q\xe2\x87}\xba+\xe4\x87\xaf~' # TODO @@ -120,4 +124,4 @@ def test_64bit(): assert mmh3.hash(a) == -1988950868 assert mmh3.hash64(a) == (-6319308327427928234, -8156928649350215884) assert mmh3.hash128(a) == 189813591698865711411311444615608766294 - assert mmh3.hash_bytes(a) == b'V\x8f}\xad\x8eNM\xa84\x07FU\x9c\xc4\xcc\x8e' \ No newline at end of file + assert mmh3.hash_bytes(a) == b'V\x8f}\xad\x8eNM\xa84\x07FU\x9c\xc4\xcc\x8e'