Mercurial > hg
changeset 25015:b3a68fb8b859
dirs: back out forward-searching in finddirs()
This backs out the changes below. The next patch will implement a
faster algorithm based on backward-walking in finddirs().
67241ee427cf (dirs._addpath: reinstate use of Py_CLEAR, 2015-04-07)
6f0e6fa9fdd7 (dirs._addpath: don't mutate Python strings after exposing them (issue4589), 2015-04-06)
1a9efc312700 (dirs.addpath: rework algorithm to search forward, 2015-03-27)
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 08 May 2015 15:09:28 -0700 |
parents | 7e5d5160073b |
children | 42e89b87ca79 |
files | mercurial/dirs.c |
diffstat | 1 files changed, 16 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirs.c Wed Apr 15 08:19:36 2015 -0700 +++ b/mercurial/dirs.c Fri May 08 15:09:28 2015 -0700 @@ -9,7 +9,6 @@ #define PY_SSIZE_T_CLEAN #include <Python.h> -#include <string.h> #include "util.h" /* @@ -33,19 +32,23 @@ { const char *s = PyString_AS_STRING(path); - const char *ret = strchr(s + pos, '/'); - return (ret != NULL) ? (ret - s) : -1; + while (pos != -1) { + if (s[pos] == '/') + break; + pos -= 1; + } + + return pos; } static int _addpath(PyObject *dirs, PyObject *path) { - char *cpath = PyString_AS_STRING(path); - Py_ssize_t len = PyString_GET_SIZE(path); - Py_ssize_t pos = -1; + const char *cpath = PyString_AS_STRING(path); + Py_ssize_t pos = PyString_GET_SIZE(path); PyObject *key = NULL; int ret = -1; - while ((pos = _finddir(path, pos + 1)) != -1) { + while ((pos = _finddir(path, pos - 1)) != -1) { PyObject *val; /* It's likely that every prefix already has an entry @@ -53,18 +56,10 @@ deallocating a string for each prefix we check. */ if (key != NULL) ((PyStringObject *)key)->ob_shash = -1; - else if (pos != 0) { - /* pos >= 1, which means that len >= 2. This is - guaranteed to produce a non-interned string. */ - key = PyString_FromStringAndSize(cpath, len); - if (key == NULL) - goto bail; - } else { - /* pos == 0, which means we need to increment the dir - count for the empty string. We need to make sure we - don't muck around with interned strings, so throw it - away later. */ - key = PyString_FromString(""); + else { + /* Force Python to not reuse a small shared string. */ + key = PyString_FromStringAndSize(cpath, + pos < 2 ? 2 : pos); if (key == NULL) goto bail; } @@ -74,10 +69,6 @@ val = PyDict_GetItem(dirs, key); if (val != NULL) { PyInt_AS_LONG(val) += 1; - if (pos != 0) - PyString_AS_STRING(key)[pos] = '/'; - else - key = NULL; continue; } @@ -92,9 +83,6 @@ Py_DECREF(val); if (ret == -1) goto bail; - - /* Clear the key out since we've already exposed it to Python - and can't mutate it further. */ Py_CLEAR(key); } ret = 0; @@ -107,11 +95,11 @@ static int _delpath(PyObject *dirs, PyObject *path) { - Py_ssize_t pos = -1; + Py_ssize_t pos = PyString_GET_SIZE(path); PyObject *key = NULL; int ret = -1; - while ((pos = _finddir(path, pos + 1)) != -1) { + while ((pos = _finddir(path, pos - 1)) != -1) { PyObject *val; key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);