Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 1 | #include <Python.h> |
| 2 | |
| 3 | static PyObject * hashFunction(PyObject *self, PyObject *args, PyObject *kw) |
| 4 | { |
| 5 | PyStringObject *a; |
| 6 | register int len; |
| 7 | register unsigned char *p; |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 8 | register unsigned long x; |
| 9 | unsigned long ulSeed; |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 10 | unsigned long cchSeed; |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 11 | unsigned long cHashElements; |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 12 | |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 13 | if (!PyArg_ParseTuple(args, "llOl:hash", |
| 14 | &ulSeed, &cchSeed, &a, &cHashElements)) |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 15 | return NULL; |
| 16 | if (!PyString_Check(a)) |
| 17 | { |
| 18 | PyErr_SetString(PyExc_TypeError, "arg 3 needs to be a string"); |
| 19 | return NULL; |
| 20 | } |
| 21 | |
| 22 | len = a->ob_size; |
| 23 | p = (unsigned char *) a->ob_sval; |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 24 | x = ulSeed; |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 25 | while (--len >= 0) |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 26 | { |
| 27 | /* (1000003 * x) ^ *p++ |
| 28 | * translated to handle > 32 bit longs |
| 29 | */ |
| 30 | x = (0xf4243 * x); |
| 31 | x = x & 0xFFFFFFFF; |
| 32 | x = x ^ *p++; |
| 33 | } |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 34 | x ^= a->ob_size + cchSeed; |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 35 | if (x == 0xFFFFFFFF) |
| 36 | x = 0xfffffffe; |
| 37 | if (x & 0x80000000) |
| 38 | { |
| 39 | /* Emulate Python 32-bit signed (2's complement) |
| 40 | * modulo operation |
| 41 | */ |
| 42 | x = (~x & 0xFFFFFFFF) + 1; |
| 43 | x %= cHashElements; |
| 44 | if (x != 0) |
| 45 | { |
| 46 | x = x + (~cHashElements & 0xFFFFFFFF) + 1; |
| 47 | x = (~x & 0xFFFFFFFF) + 1; |
| 48 | } |
| 49 | } |
| 50 | else |
| 51 | x %= cHashElements; |
| 52 | return PyInt_FromLong((long)x); |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | static PyObject * calcSeed(PyObject *self, PyObject *args, PyObject *kw) |
| 56 | { |
| 57 | PyStringObject *a; |
| 58 | register int len; |
| 59 | register unsigned char *p; |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 60 | register unsigned long x; |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 61 | |
| 62 | if (!PyString_Check(args)) |
| 63 | { |
| 64 | PyErr_SetString(PyExc_TypeError, "arg 1 expected a string, but didn't get it."); |
| 65 | return NULL; |
| 66 | } |
| 67 | |
| 68 | a = (PyStringObject *)args; |
| 69 | |
| 70 | len = a->ob_size; |
| 71 | p = (unsigned char *) a->ob_sval; |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 72 | x = (*p << 7) & 0xFFFFFFFF; |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 73 | while (--len >= 0) |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 74 | { |
| 75 | /* (1000003 * x) ^ *p++ |
| 76 | * translated to handle > 32 bit longs |
| 77 | */ |
| 78 | x = (0xf4243 * x); |
| 79 | x = x & 0xFFFFFFFF; |
| 80 | x = x ^ *p++; |
| 81 | } |
| 82 | return PyInt_FromLong((long)x); |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | |
| 86 | static struct PyMethodDef hashMethods[] = { |
| 87 | { "calcSeed", calcSeed, 0, NULL }, |
| 88 | { "hash", hashFunction, 0, NULL }, |
| 89 | { NULL, NULL, 0, NULL } /* sentinel */ |
| 90 | }; |
| 91 | |
| 92 | #ifdef _MSC_VER |
| 93 | _declspec(dllexport) |
| 94 | #endif |
Thomas Wouters | 7889010 | 2000-07-22 19:25:51 +0000 | [diff] [blame] | 95 | void initperfhash(void) |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 96 | { |
| 97 | PyObject *m; |
| 98 | |
| 99 | m = Py_InitModule4("perfhash", hashMethods, |
| 100 | NULL, NULL, PYTHON_API_VERSION); |
| 101 | if ( m == NULL ) |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 102 | Py_FatalError("can't initialize module perfhash"); |
Marc-André Lemburg | 93c409a | 2000-06-28 16:48:05 +0000 | [diff] [blame] | 103 | } |
Jeremy Hylton | 4d6381d | 2000-07-26 03:56:06 +0000 | [diff] [blame] | 104 | |
| 105 | |
| 106 | |
| 107 | |
| 108 | |
| 109 | |
| 110 | |
| 111 | |
| 112 | |
| 113 | |
| 114 | |