Mercurial > hg
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?" |