Patchwork [4,of,7,resend] pathencode: implement hashed encoding in C

login
register
mail settings
Submitter Bryan O'Sullivan
Date Dec. 12, 2012, 9:10 p.m.
Message ID <719157ceff748fbe5d55.1355346659@australite.local>
Download mbox | patch
Permalink /patch/73/
State Accepted
Commit 79f4a2a8f248f37fd6926d469eb751c347d23552
Delegated to: Matt Mackall
Headers show

Comments

Bryan O'Sullivan - Dec. 12, 2012, 9:10 p.m.
# HG changeset patch
# User Bryan O'Sullivan <bryano at fb.com>
# Date 1355346576 28800
# Node ID 719157ceff748fbe5d55af773c53ec459fef20ad
# Parent  10f8c51e309311a5882679ddf56b9bdb8cd444e5
pathencode: implement hashed encoding in C

This will be used by an upcoming patch.

Patch

diff --git a/mercurial/pathencode.c b/mercurial/pathencode.c
--- a/mercurial/pathencode.c
+++ b/mercurial/pathencode.c
@@ -523,6 +523,19 @@  PyObject *lowerencode(PyObject *self, Py
 	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 @@  static int sha1hash(char hash[20], const
 	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.
  *