##// END OF EJS Templates
parsers: inline fields of dirstate values in C version...
Siddharth Agarwal -
r21809:e250b830 default
parent child Browse files
Show More
@@ -138,25 +138,12 b' static int dirs_fromdict(PyObject *dirs,'
138 138 return -1;
139 139 }
140 140 if (skipchar) {
141 PyObject *st;
142
143 if (!PyTuple_Check(value) ||
144 PyTuple_GET_SIZE(value) == 0) {
141 if (!dirstate_tuple_check(value)) {
145 142 PyErr_SetString(PyExc_TypeError,
146 "expected non-empty tuple");
143 "expected a dirstate tuple");
147 144 return -1;
148 145 }
149
150 st = PyTuple_GET_ITEM(value, 0);
151
152 if (!PyString_Check(st) || PyString_GET_SIZE(st) == 0) {
153 PyErr_SetString(PyExc_TypeError,
154 "expected non-empty string "
155 "at tuple index 0");
156 return -1;
157 }
158
159 if (PyString_AS_STRING(st)[0] == skipchar)
146 if (((dirstateTupleObject *)value)->state == skipchar)
160 147 continue;
161 148 }
162 149
@@ -14,9 +14,7 b' propertycache = util.propertycache'
14 14 filecache = scmutil.filecache
15 15 _rangemask = 0x7fffffff
16 16
17 def dirstatetuple(*x):
18 # x is a tuple
19 return x
17 dirstatetuple = parsers.dirstatetuple
20 18
21 19 class repocache(filecache):
22 20 """filecache for files in .hg/"""
@@ -153,6 +153,122 b' quit:'
153 153 return NULL;
154 154 }
155 155
156 static inline dirstateTupleObject *make_dirstate_tuple(char state, int mode,
157 int size, int mtime)
158 {
159 dirstateTupleObject *t = PyObject_New(dirstateTupleObject,
160 &dirstateTupleType);
161 if (!t)
162 return NULL;
163 t->state = state;
164 t->mode = mode;
165 t->size = size;
166 t->mtime = mtime;
167 return t;
168 }
169
170 static PyObject *dirstate_tuple_new(PyTypeObject *subtype, PyObject *args,
171 PyObject *kwds)
172 {
173 /* We do all the initialization here and not a tp_init function because
174 * dirstate_tuple is immutable. */
175 dirstateTupleObject *t;
176 char state;
177 int size, mode, mtime;
178 if (!PyArg_ParseTuple(args, "ciii", &state, &mode, &size, &mtime))
179 return NULL;
180
181 t = (dirstateTupleObject *)subtype->tp_alloc(subtype, 1);
182 if (!t)
183 return NULL;
184 t->state = state;
185 t->mode = mode;
186 t->size = size;
187 t->mtime = mtime;
188
189 return (PyObject *)t;
190 }
191
192 static void dirstate_tuple_dealloc(PyObject *o)
193 {
194 PyObject_Del(o);
195 }
196
197 static Py_ssize_t dirstate_tuple_length(PyObject *o)
198 {
199 return 4;
200 }
201
202 static PyObject *dirstate_tuple_item(PyObject *o, Py_ssize_t i)
203 {
204 dirstateTupleObject *t = (dirstateTupleObject *)o;
205 switch (i) {
206 case 0:
207 return PyBytes_FromStringAndSize(&t->state, 1);
208 case 1:
209 return PyInt_FromLong(t->mode);
210 case 2:
211 return PyInt_FromLong(t->size);
212 case 3:
213 return PyInt_FromLong(t->mtime);
214 default:
215 PyErr_SetString(PyExc_IndexError, "index out of range");
216 return NULL;
217 }
218 }
219
220 static PySequenceMethods dirstate_tuple_sq = {
221 dirstate_tuple_length, /* sq_length */
222 0, /* sq_concat */
223 0, /* sq_repeat */
224 dirstate_tuple_item, /* sq_item */
225 0, /* sq_ass_item */
226 0, /* sq_contains */
227 0, /* sq_inplace_concat */
228 0 /* sq_inplace_repeat */
229 };
230
231 PyTypeObject dirstateTupleType = {
232 PyVarObject_HEAD_INIT(NULL, 0)
233 "dirstate_tuple", /* tp_name */
234 sizeof(dirstateTupleObject),/* tp_basicsize */
235 0, /* tp_itemsize */
236 (destructor)dirstate_tuple_dealloc, /* tp_dealloc */
237 0, /* tp_print */
238 0, /* tp_getattr */
239 0, /* tp_setattr */
240 0, /* tp_compare */
241 0, /* tp_repr */
242 0, /* tp_as_number */
243 &dirstate_tuple_sq, /* tp_as_sequence */
244 0, /* tp_as_mapping */
245 0, /* tp_hash */
246 0, /* tp_call */
247 0, /* tp_str */
248 0, /* tp_getattro */
249 0, /* tp_setattro */
250 0, /* tp_as_buffer */
251 Py_TPFLAGS_DEFAULT, /* tp_flags */
252 "dirstate tuple", /* tp_doc */
253 0, /* tp_traverse */
254 0, /* tp_clear */
255 0, /* tp_richcompare */
256 0, /* tp_weaklistoffset */
257 0, /* tp_iter */
258 0, /* tp_iternext */
259 0, /* tp_methods */
260 0, /* tp_members */
261 0, /* tp_getset */
262 0, /* tp_base */
263 0, /* tp_dict */
264 0, /* tp_descr_get */
265 0, /* tp_descr_set */
266 0, /* tp_dictoffset */
267 0, /* tp_init */
268 0, /* tp_alloc */
269 dirstate_tuple_new, /* tp_new */
270 };
271
156 272 static PyObject *parse_dirstate(PyObject *self, PyObject *args)
157 273 {
158 274 PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
@@ -192,11 +308,8 b' static PyObject *parse_dirstate(PyObject'
192 308 goto quit;
193 309 }
194 310
195 entry = Py_BuildValue("ciii", state, mode, size, mtime);
196 if (!entry)
197 goto quit;
198 PyObject_GC_UnTrack(entry); /* don't waste time with this */
199
311 entry = (PyObject *)make_dirstate_tuple(state, mode, size,
312 mtime);
200 313 cpos = memchr(cur, 0, flen);
201 314 if (cpos) {
202 315 fname = PyBytes_FromStringAndSize(cur, cpos - cur);
@@ -316,33 +429,30 b' static PyObject *pack_dirstate(PyObject '
316 429 p += 20;
317 430
318 431 for (pos = 0; PyDict_Next(map, &pos, &k, &v); ) {
432 dirstateTupleObject *tuple;
433 char state;
319 434 uint32_t mode, size, mtime;
320 435 Py_ssize_t len, l;
321 436 PyObject *o;
322 char *s, *t;
437 char *t;
323 438
324 if (!PyTuple_Check(v) || PyTuple_GET_SIZE(v) != 4) {
325 PyErr_SetString(PyExc_TypeError, "expected a 4-tuple");
439 if (!dirstate_tuple_check(v)) {
440 PyErr_SetString(PyExc_TypeError,
441 "expected a dirstate tuple");
326 442 goto bail;
327 443 }
328 o = PyTuple_GET_ITEM(v, 0);
329 if (PyString_AsStringAndSize(o, &s, &l) == -1 || l != 1) {
330 PyErr_SetString(PyExc_TypeError, "expected one byte");
331 goto bail;
332 }
333 *p++ = *s;
334 if (getintat(v, 1, &mode) == -1)
335 goto bail;
336 if (getintat(v, 2, &size) == -1)
337 goto bail;
338 if (getintat(v, 3, &mtime) == -1)
339 goto bail;
340 if (*s == 'n' && mtime == (uint32_t)now) {
444 tuple = (dirstateTupleObject *)v;
445
446 state = tuple->state;
447 mode = tuple->mode;
448 size = tuple->size;
449 mtime = tuple->mtime;
450 if (state == 'n' && mtime == (uint32_t)now) {
341 451 /* See pure/parsers.py:pack_dirstate for why we do
342 452 * this. */
343 453 mtime = -1;
344 mtime_unset = Py_BuildValue(
345 "ciii", *s, mode, size, mtime);
454 mtime_unset = (PyObject *)make_dirstate_tuple(
455 state, mode, size, mtime);
346 456 if (!mtime_unset)
347 457 goto bail;
348 458 if (PyDict_SetItem(map, k, mtime_unset) == -1)
@@ -350,6 +460,7 b' static PyObject *pack_dirstate(PyObject '
350 460 Py_DECREF(mtime_unset);
351 461 mtime_unset = NULL;
352 462 }
463 *p++ = state;
353 464 putbe32(mode, p);
354 465 putbe32(size, p + 4);
355 466 putbe32(mtime, p + 8);
@@ -2021,11 +2132,14 b' static void module_init(PyObject *mod)'
2021 2132 dirs_module_init(mod);
2022 2133
2023 2134 indexType.tp_new = PyType_GenericNew;
2024 if (PyType_Ready(&indexType) < 0)
2135 if (PyType_Ready(&indexType) < 0 ||
2136 PyType_Ready(&dirstateTupleType) < 0)
2025 2137 return;
2026 2138 Py_INCREF(&indexType);
2027
2028 2139 PyModule_AddObject(mod, "index", (PyObject *)&indexType);
2140 Py_INCREF(&dirstateTupleType);
2141 PyModule_AddObject(mod, "dirstatetuple",
2142 (PyObject *)&dirstateTupleType);
2029 2143
2030 2144 nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0,
2031 2145 -1, -1, -1, -1, nullid, 20);
@@ -15,6 +15,12 b' import struct, zlib, cStringIO'
15 15 _decompress = zlib.decompress
16 16 _sha = util.sha1
17 17
18 # Some code below makes tuples directly because it's more convenient. However,
19 # code outside this module should always use dirstatetuple.
20 def dirstatetuple(*x):
21 # x is a tuple
22 return x
23
18 24 def parse_manifest(mfdict, fdict, lines):
19 25 for l in lines.splitlines():
20 26 f, n = l.split('\0')
@@ -104,7 +110,7 b' def pack_dirstate(dmap, copymap, pl, now'
104 110 # dirstate, forcing future 'status' calls to compare the
105 111 # contents of the file if the size is the same. This prevents
106 112 # mistakenly treating such files as clean.
107 e = (e[0], e[1], e[2], -1)
113 e = dirstatetuple(e[0], e[1], e[2], -1)
108 114 dmap[f] = e
109 115
110 116 if f in copymap:
@@ -151,6 +151,17 b' typedef unsigned __int64 uint64_t;'
151 151 #define inline __inline
152 152 #endif
153 153
154 typedef struct {
155 PyObject_HEAD
156 char state;
157 int mode;
158 int size;
159 int mtime;
160 } dirstateTupleObject;
161
162 PyTypeObject dirstateTupleType;
163 #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateTupleType)
164
154 165 static inline uint32_t getbe32(const char *c)
155 166 {
156 167 const unsigned char *d = (const unsigned char *)c;
General Comments 0
You need to be logged in to leave comments. Login now