changeset 18433:79f4a2a8f248

pathencode: implement hashed encoding in C This will be used by an upcoming patch.
author Bryan O'Sullivan <bryano@fb.com>
date Wed, 12 Dec 2012 13:09:36 -0800
parents 39954be8ece7
children 3807ec0c6bba
files mercurial/pathencode.c
diffstat 1 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/pathencode.c	Wed Dec 12 13:09:35 2012 -0800
+++ b/mercurial/pathencode.c	Wed Dec 12 13:09:36 2012 -0800
@@ -523,6 +523,19 @@
 	return ret;
 }
 
+/* See store.py:_auxencode for a description. */
+static Py_ssize_t auxencode(char *dest, size_t destsize,
+			    const char *src, Py_ssize_t len)
+{
+	static const uint32_t twobytes[8];
+
+	static const uint32_t onebyte[8] = {
+		~0, 0xffff3ffe, ~0, ~0, ~0, ~0, ~0, ~0,
+	};
+
+	return _encode(twobytes, onebyte, dest, 0, destsize, src, len, 0);
+}
+
 static PyObject *hashmangle(const char *src, Py_ssize_t len, const char sha[20])
 {
 	static const Py_ssize_t dirprefixlen = 8;
@@ -683,6 +696,30 @@
 	return 0;
 }
 
+static PyObject *hashencode(const char *src, Py_ssize_t len)
+{
+	const Py_ssize_t baselen = (len - 5) * 3;
+#ifndef _MSC_VER
+	/* alloca is surprisingly slow, so avoid when possible */
+	char dired[baselen];
+	char lowered[baselen];
+	char auxed[baselen];
+#else
+	char *dired = alloca(baselen);
+	char *lowered = alloca(baselen);
+	char *auxed = alloca(baselen);
+#endif
+	Py_ssize_t dirlen, lowerlen, auxlen;
+	char sha[20];
+
+	dirlen = _encodedir(dired, baselen, src, len);
+	if (sha1hash(sha, dired, dirlen - 1) == -1)
+		return NULL;
+	lowerlen = _lowerencode(lowered, baselen, dired + 5, dirlen - 5);
+	auxlen = auxencode(auxed, baselen, lowered, lowerlen);
+	return hashmangle(auxed, auxlen, sha);
+}
+
 /*
  * We currently implement only basic encoding.
  *