Mercurial > hg-stable
changeset 18431:3aa9b2136593
pathencode: add a SHA-1 hash function
This will be used by an upcoming patch.
This calls out to the Python hash implementation.
An earlier version of this function implemented SHA-1 directly, but
the amount of extra code didn't seem like a good tradeoff compared
to the small big-picture increase in performance (long paths are
uncommon).
author | Bryan O'Sullivan <bryano@fb.com> |
---|---|
date | Wed, 12 Dec 2012 13:09:34 -0800 |
parents | 0459c6555f69 |
children | 39954be8ece7 |
files | mercurial/pathencode.c |
diffstat | 1 files changed, 53 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/pathencode.c Wed Dec 12 13:09:33 2012 -0800 +++ b/mercurial/pathencode.c Wed Dec 12 13:09:34 2012 -0800 @@ -524,6 +524,59 @@ } /* + * Avoiding a trip through Python would improve performance by 50%, + * but we don't encounter enough long names to be worth the code. + */ +static int sha1hash(char hash[20], const char *str, Py_ssize_t len) +{ + static PyObject *shafunc; + PyObject *shaobj, *hashobj; + + if (shafunc == NULL) { + PyObject *util, *name = PyString_FromString("mercurial.util"); + + if (name == NULL) + return -1; + + util = PyImport_Import(name); + Py_DECREF(name); + + if (util == NULL) { + PyErr_SetString(PyExc_ImportError, "mercurial.util"); + return -1; + } + shafunc = PyObject_GetAttrString(util, "sha1"); + Py_DECREF(util); + + if (shafunc == NULL) { + PyErr_SetString(PyExc_AttributeError, + "module 'mercurial.util' has no " + "attribute 'sha1'"); + return -1; + } + } + + shaobj = PyObject_CallFunction(shafunc, "s#", str, len); + + if (shaobj == NULL) + return -1; + + hashobj = PyObject_CallMethod(shaobj, "digest", ""); + Py_DECREF(shaobj); + + if (!PyString_Check(hashobj) || PyString_GET_SIZE(hashobj) != 20) { + PyErr_SetString(PyExc_TypeError, + "result of digest is not a 20-byte hash"); + Py_DECREF(hashobj); + return -1; + } + + memcpy(hash, PyString_AS_STRING(hashobj), 20); + Py_DECREF(hashobj); + return 0; +} + +/* * We currently implement only basic encoding. * * If a name is too long to encode due to Windows path name limits,