##// END OF EJS Templates
dirs.addpath: rework algorithm to search forward...
Siddharth Agarwal -
r24486:1a9efc31 default
parent child Browse files
Show More
@@ -9,6 +9,7
9
9
10 #define PY_SSIZE_T_CLEAN
10 #define PY_SSIZE_T_CLEAN
11 #include <Python.h>
11 #include <Python.h>
12 #include <string.h>
12 #include "util.h"
13 #include "util.h"
13
14
14 /*
15 /*
@@ -32,23 +33,19 static inline Py_ssize_t _finddir(PyObje
32 {
33 {
33 const char *s = PyString_AS_STRING(path);
34 const char *s = PyString_AS_STRING(path);
34
35
35 while (pos != -1) {
36 const char *ret = strchr(s + pos, '/');
36 if (s[pos] == '/')
37 return (ret != NULL) ? (ret - s) : -1;
37 break;
38 pos -= 1;
39 }
40
41 return pos;
42 }
38 }
43
39
44 static int _addpath(PyObject *dirs, PyObject *path)
40 static int _addpath(PyObject *dirs, PyObject *path)
45 {
41 {
46 const char *cpath = PyString_AS_STRING(path);
42 char *cpath = PyString_AS_STRING(path);
47 Py_ssize_t pos = PyString_GET_SIZE(path);
43 Py_ssize_t len = PyString_GET_SIZE(path);
44 Py_ssize_t pos = -1;
48 PyObject *key = NULL;
45 PyObject *key = NULL;
49 int ret = -1;
46 int ret = -1;
50
47
51 while ((pos = _finddir(path, pos - 1)) != -1) {
48 while ((pos = _finddir(path, pos + 1)) != -1) {
52 PyObject *val;
49 PyObject *val;
53
50
54 /* It's likely that every prefix already has an entry
51 /* It's likely that every prefix already has an entry
@@ -56,10 +53,18 static int _addpath(PyObject *dirs, PyOb
56 deallocating a string for each prefix we check. */
53 deallocating a string for each prefix we check. */
57 if (key != NULL)
54 if (key != NULL)
58 ((PyStringObject *)key)->ob_shash = -1;
55 ((PyStringObject *)key)->ob_shash = -1;
59 else {
56 else if (pos != 0) {
60 /* Force Python to not reuse a small shared string. */
57 /* pos >= 1, which means that len >= 2. This is
61 key = PyString_FromStringAndSize(cpath,
58 guaranteed to produce a non-interned string. */
62 pos < 2 ? 2 : pos);
59 key = PyString_FromStringAndSize(cpath, len);
60 if (key == NULL)
61 goto bail;
62 } else {
63 /* pos == 0, which means we need to increment the dir
64 count for the empty string. We need to make sure we
65 don't muck around with interned strings, so throw it
66 away later. */
67 key = PyString_FromString("");
63 if (key == NULL)
68 if (key == NULL)
64 goto bail;
69 goto bail;
65 }
70 }
@@ -69,6 +74,10 static int _addpath(PyObject *dirs, PyOb
69 val = PyDict_GetItem(dirs, key);
74 val = PyDict_GetItem(dirs, key);
70 if (val != NULL) {
75 if (val != NULL) {
71 PyInt_AS_LONG(val) += 1;
76 PyInt_AS_LONG(val) += 1;
77 if (pos != 0)
78 PyString_AS_STRING(key)[pos] = '/';
79 else
80 key = NULL;
72 continue;
81 continue;
73 }
82 }
74
83
@@ -83,6 +92,11 static int _addpath(PyObject *dirs, PyOb
83 Py_DECREF(val);
92 Py_DECREF(val);
84 if (ret == -1)
93 if (ret == -1)
85 goto bail;
94 goto bail;
95
96 if (pos != 0)
97 PyString_AS_STRING(key)[pos] = '/';
98 else
99 key = NULL;
86 Py_CLEAR(key);
100 Py_CLEAR(key);
87 }
101 }
88 ret = 0;
102 ret = 0;
@@ -95,11 +109,11 bail:
95
109
96 static int _delpath(PyObject *dirs, PyObject *path)
110 static int _delpath(PyObject *dirs, PyObject *path)
97 {
111 {
98 Py_ssize_t pos = PyString_GET_SIZE(path);
112 Py_ssize_t pos = -1;
99 PyObject *key = NULL;
113 PyObject *key = NULL;
100 int ret = -1;
114 int ret = -1;
101
115
102 while ((pos = _finddir(path, pos - 1)) != -1) {
116 while ((pos = _finddir(path, pos + 1)) != -1) {
103 PyObject *val;
117 PyObject *val;
104
118
105 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);
119 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);
General Comments 0
You need to be logged in to leave comments. Login now