[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