[PATCH 1 of 3 v4] store: implement fncache path mangling code in C
Adrian Buehlmann
adrian at cadifra.com
Fri Sep 7 14:07:56 CDT 2012
On 2012-09-07 01:31, Bryan O'Sullivan wrote:
> +static PyObject *hashmangle(const char *src, Py_ssize_t len, const char sha[20])
> +{
> + static const Py_ssize_t dirprefixlen = 8;
> + static const Py_ssize_t maxshortdirslen = 68;
> + char *dest;
> + PyObject *ret;
> +
> + Py_ssize_t i, d, p, lastslash = len - 1, lastdot = -1;
> + Py_ssize_t destsize, destlen = 0, slop, used;
Bryan, can I ask you what "slop" means?
> +
> + while (lastslash >= 0 && src[lastslash] != '/') {
> + if (src[lastslash] == '.' && lastdot == -1)
> + lastdot = lastslash;
> + lastslash--;
> + }
> +
> + destsize = 170;
> + if (lastdot >= 0)
> + destsize += len - lastdot - 1;
> +
> + ret = PyString_FromStringAndSize(NULL, destsize);
> + if (ret == NULL)
> + return NULL;
> +
> + dest = PyString_AS_STRING(ret);
> + memcopy(dest, &destlen, destsize, "dh/", 3);
> +
> + for (i = d = p = 0; i < lastslash; i++, p++) {
> + if (src[i] == '/') {
> + char d = destlen > 0 ? dest[destlen - 1] : 0;
> + /* After truncation, a directory name may end
> + in a space or dot. */
> + if (d == '.' || d == ' ') {
> + destlen--;
> + charcopy(dest, &destlen, destsize, '_');
> + }
> + if (destlen > maxshortdirslen)
> + break;
> + charcopy(dest, &destlen, destsize, src[i]);
> + p = -1;
> + }
> + else if (p < dirprefixlen)
> + charcopy(dest, &destlen, destsize, src[i]);
> + }
> +
> + if (destlen > maxshortdirslen + 3)
> + do {
> + destlen--;
> + } while (destlen > 0 && dest[destlen] != '/');
> +
> + if (destlen > 3)
> + charcopy(dest, &destlen, destsize, '/');
> +
> + used = destlen + 40;
> + if (lastdot >= 0)
> + used += len - lastdot - 1;
> + slop = maxstorepathlen - used;
> + if (slop > 0) {
> + Py_ssize_t basenamelen =
> + lastslash >= 0 ? len - lastslash - 2 : len - 1;
> +
> + if (basenamelen > slop)
> + basenamelen = slop;
> + if (basenamelen > 0)
> + memcopy(dest, &destlen, destsize, &src[lastslash + 1],
> + basenamelen);
> + }
> +
> + for (i = 0; i < 20; i++)
> + hexencode(dest, &destlen, destsize, sha[i]);
> +
> + if (lastdot >= 0)
> + memcopy(dest, &destlen, destsize, &src[lastdot],
> + len - lastdot - 1);
> +
> + PyString_GET_SIZE(ret) = destlen;
> +
> + return ret;
> +}
If I would have had to write such kind of code, I would be almost 100%
sure *I* would have (unintentionally) inserted at least 5 bugs in it.
But if you guys feel comfortable with it, ok.
(I'm currently not able to tell whether this code ok).
More information about the Mercurial-devel
mailing list