comparison mercurial/osutil.c @ 18026:ddc0323db78b

osutil: write a C implementation of statfiles for unix This makes a big difference to performance. In a clean working directory containing 170,000 files, performance of "hg --time diff" improves from 2.38 seconds to 1.69.
author Bryan O'Sullivan <bryano@fb.com>
date Mon, 03 Dec 2012 12:40:24 -0800
parents 9b05b31b413c
children 4ca434500dbf
comparison
equal deleted inserted replaced
18021:9b05b31b413c 18026:ddc0323db78b
387 #endif 387 #endif
388 error_value: 388 error_value:
389 return ret; 389 return ret;
390 } 390 }
391 391
392 static PyObject *statfiles(PyObject *self, PyObject *args)
393 {
394 PyObject *names, *stats;
395 Py_ssize_t i, count;
396
397 if (!PyArg_ParseTuple(args, "O:statfiles", &names))
398 return NULL;
399
400 count = PySequence_Length(names);
401 if (count == -1) {
402 PyErr_SetString(PyExc_TypeError, "not a sequence");
403 return NULL;
404 }
405
406 stats = PyList_New(count);
407 if (stats == NULL)
408 return NULL;
409
410 for (i = 0; i < count; i++) {
411 PyObject *stat;
412 struct stat st;
413 int ret, kind;
414 char *path;
415
416 path = PyString_AsString(PySequence_GetItem(names, i));
417 if (path == NULL) {
418 PyErr_SetString(PyExc_TypeError, "not a string");
419 goto bail;
420 }
421 ret = lstat(path, &st);
422 kind = st.st_mode & S_IFMT;
423 if (ret != -1 && (kind == S_IFREG || kind == S_IFLNK)) {
424 stat = makestat(&st);
425 if (stat == NULL)
426 goto bail;
427 PyList_SET_ITEM(stats, i, stat);
428 } else {
429 Py_INCREF(Py_None);
430 PyList_SET_ITEM(stats, i, Py_None);
431 }
432 }
433
434 return stats;
435
436 bail:
437 Py_DECREF(stats);
438 return NULL;
439 }
440
392 #endif /* ndef _WIN32 */ 441 #endif /* ndef _WIN32 */
393 442
394 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) 443 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
395 { 444 {
396 PyObject *statobj = NULL; /* initialize - optional arg */ 445 PyObject *statobj = NULL; /* initialize - optional arg */
551 "list a directory\n"}, 600 "list a directory\n"},
552 #ifdef _WIN32 601 #ifdef _WIN32
553 {"posixfile", (PyCFunction)posixfile, METH_VARARGS | METH_KEYWORDS, 602 {"posixfile", (PyCFunction)posixfile, METH_VARARGS | METH_KEYWORDS,
554 "Open a file with POSIX-like semantics.\n" 603 "Open a file with POSIX-like semantics.\n"
555 "On error, this function may raise either a WindowsError or an IOError."}, 604 "On error, this function may raise either a WindowsError or an IOError."},
605 #else
606 {"statfiles", (PyCFunction)statfiles, METH_VARARGS | METH_KEYWORDS,
607 "stat a series of files or symlinks\n"
608 "Returns None for non-existent entries and entries of other types.\n"},
556 #endif 609 #endif
557 #ifdef __APPLE__ 610 #ifdef __APPLE__
558 { 611 {
559 "isgui", (PyCFunction)isgui, METH_NOARGS, 612 "isgui", (PyCFunction)isgui, METH_NOARGS,
560 "Is a CoreGraphics session available?" 613 "Is a CoreGraphics session available?"