60e51fd2764291df2332f36ff478777627d92b57Sumit Bose/*
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose Authors:
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose Sumit Bose <sbose@redhat.com>
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose Copyright (C) 2012 Red Hat
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose This program is free software; you can redistribute it and/or modify
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose it under the terms of the GNU General Public License as published by
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose the Free Software Foundation; either version 3 of the License, or
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose (at your option) any later version.
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose This program is distributed in the hope that it will be useful,
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose GNU General Public License for more details.
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose You should have received a copy of the GNU General Public License
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose*/
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
69fb159e1464ef91376f56e65afa9704d5bafad8Lukas Slebodnik#include "config.h"
69fb159e1464ef91376f56e65afa9704d5bafad8Lukas Slebodnik
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose#include <Python.h>
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
69fb159e1464ef91376f56e65afa9704d5bafad8Lukas Slebodnik#include "util/sss_python.h"
3996e391054a1c02ab62e1541ae21a8204bd5d0aAmitKumar#include "shared/murmurhash3.h"
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit BosePyDoc_STRVAR(murmurhash3_doc,
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose"murmurhash3(key, key_len, seed) -> 32bit integer hash\n\
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose\n\
60e51fd2764291df2332f36ff478777627d92b57Sumit BoseCalculate the murmur hash version 3 of the first key_len bytes from key\n\
60e51fd2764291df2332f36ff478777627d92b57Sumit Boseusing the given seed."
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose);
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bosestatic PyObject * py_murmurhash3(PyObject *module, PyObject *args)
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose{
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose const char *key;
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose long key_len;
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose long long seed;
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose uint32_t hash;
41454a64c714e984423fd6e94ea89d183a73cc67Lukas Slebodnik int input_len;
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
41454a64c714e984423fd6e94ea89d183a73cc67Lukas Slebodnik if (!PyArg_ParseTuple(args, sss_py_const_p(char, "z#lL"),
41454a64c714e984423fd6e94ea89d183a73cc67Lukas Slebodnik &key, &input_len, &key_len, &seed)) {
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose PyErr_Format(PyExc_ValueError, "Invalid argument\n");
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose return NULL;
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose }
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose if (seed > UINT32_MAX || key_len > INT_MAX || key_len < 0 ||
1c42c3962577ea4b2d9ed6a8a07179d33756b3b4Fabiano Fidêncio key_len > input_len) {
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose PyErr_Format(PyExc_ValueError, "Invalid value\n");
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose return NULL;
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose }
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose hash = murmurhash3(key, key_len, seed);
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose return PyLong_FromUnsignedLong((unsigned long) hash);
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose}
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
60e51fd2764291df2332f36ff478777627d92b57Sumit Bosestatic PyMethodDef methods[] = {
56ad566af1e595dacfcc5a213d906e8070bb263cJakub Hrozek { sss_py_const_p(char, "murmurhash3"), (PyCFunction) py_murmurhash3,
56ad566af1e595dacfcc5a213d906e8070bb263cJakub Hrozek METH_VARARGS, murmurhash3_doc },
56ad566af1e595dacfcc5a213d906e8070bb263cJakub Hrozek { NULL,NULL, 0, NULL }
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose};
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#ifdef IS_PY3K
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrdastatic struct PyModuleDef pysss_murmurdef = {
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda PyModuleDef_HEAD_INIT,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda "pysss_murmur",
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda NULL,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda -1,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda methods,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda NULL,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda NULL,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda NULL,
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda NULL
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda};
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose
341a00311680a440d7f979f06c34c70d86c9367aBohuslav KabrdaPyMODINIT_FUNC
341a00311680a440d7f979f06c34c70d86c9367aBohuslav KabrdaPyInit_pysss_murmur(void)
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#else
60e51fd2764291df2332f36ff478777627d92b57Sumit BosePyMODINIT_FUNC
60e51fd2764291df2332f36ff478777627d92b57Sumit Boseinitpysss_murmur(void)
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#endif
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose{
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda PyObject *m;
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#ifdef IS_PY3K
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda m = PyModule_Create(&pysss_murmurdef);
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#else
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda m = Py_InitModule3(sss_py_const_p(char, "pysss_murmur"),
56ad566af1e595dacfcc5a213d906e8070bb263cJakub Hrozek methods, sss_py_const_p(char, "murmur hash functions"));
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#endif
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda if (m == NULL)
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda MODINITERROR;
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#ifdef IS_PY3K
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda return m;
341a00311680a440d7f979f06c34c70d86c9367aBohuslav Kabrda#endif
60e51fd2764291df2332f36ff478777627d92b57Sumit Bose}