##// END OF EJS Templates
revlog: switch to a C version of headrevs...
Bryan O'Sullivan -
r16786:2631cd5d default
parent child Browse files
Show More
@@ -534,6 +534,81 b' bail:'
534 return NULL;
534 return NULL;
535 }
535 }
536
536
537 static PyObject *index_headrevs(indexObject *self)
538 {
539 Py_ssize_t i, len, addlen;
540 char *nothead = NULL;
541 PyObject *heads;
542
543 len = index_length(self) - 1;
544 heads = PyList_New(0);
545 if (heads == NULL)
546 goto bail;
547 if (len == 0) {
548 PyObject *nullid = PyInt_FromLong(-1);
549 if (nullid == NULL || PyList_Append(heads, nullid) == -1) {
550 Py_XDECREF(nullid);
551 goto bail;
552 }
553 goto done;
554 }
555
556 nothead = calloc(len, 1);
557 if (nothead == NULL)
558 goto bail;
559
560 for (i = 0; i < self->raw_length; i++) {
561 const char *data = index_deref(self, i);
562 int parent_1 = getbe32(data + 24);
563 int parent_2 = getbe32(data + 28);
564 if (parent_1 >= 0)
565 nothead[parent_1] = 1;
566 if (parent_2 >= 0)
567 nothead[parent_2] = 1;
568 }
569
570 addlen = self->added ? PyList_GET_SIZE(self->added) : 0;
571
572 for (i = 0; i < addlen; i++) {
573 PyObject *rev = PyList_GET_ITEM(self->added, i);
574 PyObject *p1 = PyTuple_GET_ITEM(rev, 5);
575 PyObject *p2 = PyTuple_GET_ITEM(rev, 6);
576 long parent_1, parent_2;
577
578 if (!PyInt_Check(p1) || !PyInt_Check(p2)) {
579 PyErr_SetString(PyExc_TypeError,
580 "revlog parents are invalid");
581 goto bail;
582 }
583 parent_1 = PyInt_AS_LONG(p1);
584 parent_2 = PyInt_AS_LONG(p2);
585 if (parent_1 >= 0)
586 nothead[parent_1] = 1;
587 if (parent_2 >= 0)
588 nothead[parent_2] = 1;
589 }
590
591 for (i = 0; i < len; i++) {
592 PyObject *head;
593
594 if (nothead[i])
595 continue;
596 head = PyInt_FromLong(i);
597 if (head == NULL || PyList_Append(heads, head) == -1) {
598 Py_XDECREF(head);
599 goto bail;
600 }
601 }
602
603 done:
604 free(nothead);
605 return heads;
606 bail:
607 Py_XDECREF(heads);
608 free(nothead);
609 return NULL;
610 }
611
537 static inline int nt_level(const char *node, Py_ssize_t level)
612 static inline int nt_level(const char *node, Py_ssize_t level)
538 {
613 {
539 int v = node[level>>1];
614 int v = node[level>>1];
@@ -1144,6 +1219,8 b' static PyMethodDef index_methods[] = {'
1144 "clear the index caches"},
1219 "clear the index caches"},
1145 {"get", (PyCFunction)index_m_get, METH_VARARGS,
1220 {"get", (PyCFunction)index_m_get, METH_VARARGS,
1146 "get an index entry"},
1221 "get an index entry"},
1222 {"headrevs", (PyCFunction)index_headrevs, METH_NOARGS,
1223 "get head revisions"},
1147 {"insert", (PyCFunction)index_insert, METH_VARARGS,
1224 {"insert", (PyCFunction)index_insert, METH_VARARGS,
1148 "insert an index entry"},
1225 "insert an index entry"},
1149 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
1226 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
@@ -635,6 +635,10 b' class revlog(object):'
635 return (orderedout, roots, heads)
635 return (orderedout, roots, heads)
636
636
637 def headrevs(self):
637 def headrevs(self):
638 try:
639 return self.index.headrevs()
640 except AttributeError:
641 pass
638 count = len(self)
642 count = len(self)
639 if not count:
643 if not count:
640 return [nullrev]
644 return [nullrev]
General Comments 0
You need to be logged in to leave comments. Login now