##// END OF EJS Templates
dirs: use mutable integers internally...
Bryan O'Sullivan -
r18901:66d3aebe default
parent child Browse files
Show More
@@ -14,6 +14,11 b''
14 /*
14 /*
15 * This is a multiset of directory names, built from the files that
15 * This is a multiset of directory names, built from the files that
16 * appear in a dirstate or manifest.
16 * appear in a dirstate or manifest.
17 *
18 * A few implementation notes:
19 *
20 * We modify Python integers for refcounting, but those integers are
21 * never visible to Python code.
17 */
22 */
18 typedef struct {
23 typedef struct {
19 PyObject_HEAD
24 PyObject_HEAD
@@ -36,12 +41,11 b' static inline Py_ssize_t _finddir(PyObje'
36 static int _addpath(PyObject *dirs, PyObject *path)
41 static int _addpath(PyObject *dirs, PyObject *path)
37 {
42 {
38 Py_ssize_t pos = PyString_GET_SIZE(path);
43 Py_ssize_t pos = PyString_GET_SIZE(path);
39 PyObject *newval = NULL, *key = NULL;
44 PyObject *key = NULL;
40 int ret = -1;
45 int ret = -1;
41
46
42 while ((pos = _finddir(path, pos - 1)) != -1) {
47 while ((pos = _finddir(path, pos - 1)) != -1) {
43 PyObject *val;
48 PyObject *val;
44 long v = 0;
45
49
46 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);
50 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);
47
51
@@ -49,25 +53,29 b' static int _addpath(PyObject *dirs, PyOb'
49 goto bail;
53 goto bail;
50
54
51 val = PyDict_GetItem(dirs, key);
55 val = PyDict_GetItem(dirs, key);
52 if (val != NULL)
56 if (val != NULL) {
53 v = PyInt_AS_LONG(val);
57 PyInt_AS_LONG(val) += 1;
58 Py_CLEAR(key);
59 continue;
60 }
54
61
55 newval = PyInt_FromLong(v + 1);
62 /* Force Python to not reuse a small shared int. */
63 val = PyInt_FromLong(0x1eadbeef);
56
64
57 if (newval == NULL)
65 if (val == NULL)
58 goto bail;
66 goto bail;
59
67
60 ret = PyDict_SetItem(dirs, key, newval);
68 PyInt_AS_LONG(val) = 1;
69 ret = PyDict_SetItem(dirs, key, val);
70 Py_DECREF(val);
61 if (ret == -1)
71 if (ret == -1)
62 goto bail;
72 goto bail;
63 Py_CLEAR(key);
73 Py_CLEAR(key);
64 Py_CLEAR(newval);
65 }
74 }
66 ret = 0;
75 ret = 0;
67
76
68 bail:
77 bail:
69 Py_XDECREF(key);
78 Py_XDECREF(key);
70 Py_XDECREF(newval);
71
79
72 return ret;
80 return ret;
73 }
81 }
@@ -75,12 +83,11 b' bail:'
75 static int _delpath(PyObject *dirs, PyObject *path)
83 static int _delpath(PyObject *dirs, PyObject *path)
76 {
84 {
77 Py_ssize_t pos = PyString_GET_SIZE(path);
85 Py_ssize_t pos = PyString_GET_SIZE(path);
78 PyObject *newval = NULL, *key = NULL;
86 PyObject *key = NULL;
79 int ret = -1;
87 int ret = -1;
80
88
81 while ((pos = _finddir(path, pos - 1)) != -1) {
89 while ((pos = _finddir(path, pos - 1)) != -1) {
82 PyObject *val;
90 PyObject *val;
83 long v;
84
91
85 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);
92 key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos);
86
93
@@ -93,29 +100,16 b' static int _delpath(PyObject *dirs, PyOb'
93 "expected a value, found none");
100 "expected a value, found none");
94 goto bail;
101 goto bail;
95 }
102 }
96 v = PyInt_AS_LONG(val);
97
103
98 if (v <= 1) {
104 if (--PyInt_AS_LONG(val) <= 0 &&
99 if (PyDict_DelItem(dirs, key) == -1)
105 PyDict_DelItem(dirs, key) == -1)
100 goto bail;
101 continue;
102 }
103 newval = PyInt_FromLong(v - 1);
104
105 if (newval == NULL)
106 goto bail;
107
108 ret = PyDict_SetItem(dirs, key, newval);
109 if (ret == -1)
110 goto bail;
106 goto bail;
111 Py_CLEAR(key);
107 Py_CLEAR(key);
112 Py_CLEAR(newval);
113 }
108 }
114 ret = 0;
109 ret = 0;
115
110
116 bail:
111 bail:
117 Py_XDECREF(key);
112 Py_XDECREF(key);
118 Py_XDECREF(newval);
119
113
120 return ret;
114 return ret;
121 }
115 }
General Comments 0
You need to be logged in to leave comments. Login now