Mercurial > hg
comparison mercurial/parsers.c @ 31278:1c97a91a18dc
dirstate: track otherparent files same as nonnormal
Calling dirstate.setparents() is expensive in a large repo because it iterates
over every file in the dirstate. It does so to undo any merge state or
otherparent state files. Merge state files are already covered by
dirstate._nonnormalset, so we just need to track otherparent files in a similar
manner to avoid the full iteration here.
Fixing this shaves 20-25% off histedit in large repos.
I tested this by adding temporary debug logic to verify that the old files
processed in the loop matched the new files processed in the loop and running
the test suite.
author | Durham Goode <durham@fb.com> |
---|---|
date | Wed, 08 Mar 2017 17:35:20 -0800 |
parents | 6146d5acee69 |
children | fffd1abb1337 |
comparison
equal
deleted
inserted
replaced
31276:cd29673cebdb | 31278:1c97a91a18dc |
---|---|
558 Py_XDECREF(parents); | 558 Py_XDECREF(parents); |
559 return ret; | 559 return ret; |
560 } | 560 } |
561 | 561 |
562 /* | 562 /* |
563 * Build a set of non-normal entries from the dirstate dmap | 563 * Build a set of non-normal and other parent entries from the dirstate dmap |
564 */ | 564 */ |
565 static PyObject *nonnormalentries(PyObject *self, PyObject *args) | 565 static PyObject *nonnormalotherparententries(PyObject *self, PyObject *args) { |
566 { | 566 PyObject *dmap, *fname, *v; |
567 PyObject *dmap, *nonnset = NULL, *fname, *v; | 567 PyObject *nonnset = NULL, *otherpset = NULL, *result = NULL; |
568 Py_ssize_t pos; | 568 Py_ssize_t pos; |
569 | 569 |
570 if (!PyArg_ParseTuple(args, "O!:nonnormalentries", | 570 if (!PyArg_ParseTuple(args, "O!:nonnormalentries", |
571 &PyDict_Type, &dmap)) | 571 &PyDict_Type, &dmap)) |
572 goto bail; | 572 goto bail; |
573 | 573 |
574 nonnset = PySet_New(NULL); | 574 nonnset = PySet_New(NULL); |
575 if (nonnset == NULL) | 575 if (nonnset == NULL) |
576 goto bail; | |
577 | |
578 otherpset = PySet_New(NULL); | |
579 if (otherpset == NULL) | |
576 goto bail; | 580 goto bail; |
577 | 581 |
578 pos = 0; | 582 pos = 0; |
579 while (PyDict_Next(dmap, &pos, &fname, &v)) { | 583 while (PyDict_Next(dmap, &pos, &fname, &v)) { |
580 dirstateTupleObject *t; | 584 dirstateTupleObject *t; |
583 "expected a dirstate tuple"); | 587 "expected a dirstate tuple"); |
584 goto bail; | 588 goto bail; |
585 } | 589 } |
586 t = (dirstateTupleObject *)v; | 590 t = (dirstateTupleObject *)v; |
587 | 591 |
592 if (t->state == 'n' && t->size == -2) { | |
593 if (PySet_Add(otherpset, fname) == -1) { | |
594 goto bail; | |
595 } | |
596 } | |
597 | |
588 if (t->state == 'n' && t->mtime != -1) | 598 if (t->state == 'n' && t->mtime != -1) |
589 continue; | 599 continue; |
590 if (PySet_Add(nonnset, fname) == -1) | 600 if (PySet_Add(nonnset, fname) == -1) |
591 goto bail; | 601 goto bail; |
592 } | 602 } |
593 | 603 |
594 return nonnset; | 604 result = Py_BuildValue("(OO)", nonnset, otherpset); |
605 if (result == NULL) | |
606 goto bail; | |
607 return result; | |
595 bail: | 608 bail: |
596 Py_XDECREF(nonnset); | 609 Py_XDECREF(nonnset); |
610 Py_XDECREF(otherpset); | |
611 Py_XDECREF(result); | |
597 return NULL; | 612 return NULL; |
613 } | |
614 | |
615 /* | |
616 * Build a set of non-normal entries from the dirstate dmap | |
617 */ | |
618 static PyObject *nonnormalentries(PyObject *self, PyObject *args) | |
619 { | |
620 PyObject *nonnset = NULL, *combined = NULL; | |
621 | |
622 combined = nonnormalotherparententries(self, args); | |
623 if (!combined) { | |
624 return NULL; | |
625 } | |
626 | |
627 nonnset = PyTuple_GetItem(combined, 0); | |
628 if (!nonnset) { | |
629 Py_DECREF(combined); | |
630 return NULL; | |
631 } | |
632 | |
633 Py_INCREF(nonnset); | |
634 Py_DECREF(combined); | |
635 return nonnset; | |
598 } | 636 } |
599 | 637 |
600 /* | 638 /* |
601 * Efficiently pack a dirstate object into its on-disk format. | 639 * Efficiently pack a dirstate object into its on-disk format. |
602 */ | 640 */ |
2814 | 2852 |
2815 static PyMethodDef methods[] = { | 2853 static PyMethodDef methods[] = { |
2816 {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, | 2854 {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, |
2817 {"nonnormalentries", nonnormalentries, METH_VARARGS, | 2855 {"nonnormalentries", nonnormalentries, METH_VARARGS, |
2818 "create a set containing non-normal entries of given dirstate\n"}, | 2856 "create a set containing non-normal entries of given dirstate\n"}, |
2857 {"nonnormalotherparententries", nonnormalotherparententries, METH_VARARGS, | |
2858 "create a set containing non-normal and other parent entries of given " | |
2859 "dirstate\n"}, | |
2819 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"}, | 2860 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"}, |
2820 {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, | 2861 {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, |
2821 {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"}, | 2862 {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"}, |
2822 {"asciilower", asciilower, METH_VARARGS, "lowercase an ASCII string\n"}, | 2863 {"asciilower", asciilower, METH_VARARGS, "lowercase an ASCII string\n"}, |
2823 {"asciiupper", asciiupper, METH_VARARGS, "uppercase an ASCII string\n"}, | 2864 {"asciiupper", asciiupper, METH_VARARGS, "uppercase an ASCII string\n"}, |