Show More
@@ -1544,6 +1544,103 b' bail:' | |||||
1544 | } |
|
1544 | } | |
1545 |
|
1545 | |||
1546 | /* |
|
1546 | /* | |
|
1547 | * Given a (possibly overlapping) set of revs, return all the | |||
|
1548 | * common ancestors heads: heads(::args[0] and ::a[1] and ...) | |||
|
1549 | */ | |||
|
1550 | static PyObject *index_commonancestorsheads(indexObject *self, PyObject *args) | |||
|
1551 | { | |||
|
1552 | PyObject *ret = NULL, *gca = NULL; | |||
|
1553 | Py_ssize_t argcount, i, len; | |||
|
1554 | bitmask repeat = 0; | |||
|
1555 | int revcount = 0; | |||
|
1556 | int *revs; | |||
|
1557 | ||||
|
1558 | argcount = PySequence_Length(args); | |||
|
1559 | revs = malloc(argcount * sizeof(*revs)); | |||
|
1560 | if (argcount > 0 && revs == NULL) | |||
|
1561 | return PyErr_NoMemory(); | |||
|
1562 | len = index_length(self) - 1; | |||
|
1563 | ||||
|
1564 | for (i = 0; i < argcount; i++) { | |||
|
1565 | static const int capacity = 24; | |||
|
1566 | PyObject *obj = PySequence_GetItem(args, i); | |||
|
1567 | bitmask x; | |||
|
1568 | long val; | |||
|
1569 | ||||
|
1570 | if (!PyInt_Check(obj)) { | |||
|
1571 | PyErr_SetString(PyExc_TypeError, | |||
|
1572 | "arguments must all be ints"); | |||
|
1573 | goto bail; | |||
|
1574 | } | |||
|
1575 | val = PyInt_AsLong(obj); | |||
|
1576 | if (val == -1) { | |||
|
1577 | ret = PyList_New(0); | |||
|
1578 | goto done; | |||
|
1579 | } | |||
|
1580 | if (val < 0 || val >= len) { | |||
|
1581 | PyErr_SetString(PyExc_IndexError, | |||
|
1582 | "index out of range"); | |||
|
1583 | goto bail; | |||
|
1584 | } | |||
|
1585 | /* this cheesy bloom filter lets us avoid some more | |||
|
1586 | * expensive duplicate checks in the common set-is-disjoint | |||
|
1587 | * case */ | |||
|
1588 | x = 1ull << (val & 0x3f); | |||
|
1589 | if (repeat & x) { | |||
|
1590 | int k; | |||
|
1591 | for (k = 0; k < revcount; k++) { | |||
|
1592 | if (val == revs[k]) | |||
|
1593 | goto duplicate; | |||
|
1594 | } | |||
|
1595 | } | |||
|
1596 | else repeat |= x; | |||
|
1597 | if (revcount >= capacity) { | |||
|
1598 | PyErr_Format(PyExc_OverflowError, | |||
|
1599 | "bitset size (%d) > capacity (%d)", | |||
|
1600 | revcount, capacity); | |||
|
1601 | goto bail; | |||
|
1602 | } | |||
|
1603 | revs[revcount++] = (int)val; | |||
|
1604 | duplicate:; | |||
|
1605 | } | |||
|
1606 | ||||
|
1607 | if (revcount == 0) { | |||
|
1608 | ret = PyList_New(0); | |||
|
1609 | goto done; | |||
|
1610 | } | |||
|
1611 | if (revcount == 1) { | |||
|
1612 | PyObject *obj; | |||
|
1613 | ret = PyList_New(1); | |||
|
1614 | if (ret == NULL) | |||
|
1615 | goto bail; | |||
|
1616 | obj = PyInt_FromLong(revs[0]); | |||
|
1617 | if (obj == NULL) | |||
|
1618 | goto bail; | |||
|
1619 | PyList_SET_ITEM(ret, 0, obj); | |||
|
1620 | goto done; | |||
|
1621 | } | |||
|
1622 | ||||
|
1623 | gca = find_gca_candidates(self, revs, revcount); | |||
|
1624 | if (gca == NULL) | |||
|
1625 | goto bail; | |||
|
1626 | ||||
|
1627 | ret = gca; | |||
|
1628 | Py_INCREF(gca); | |||
|
1629 | ||||
|
1630 | done: | |||
|
1631 | free(revs); | |||
|
1632 | Py_XDECREF(gca); | |||
|
1633 | ||||
|
1634 | return ret; | |||
|
1635 | ||||
|
1636 | bail: | |||
|
1637 | free(revs); | |||
|
1638 | Py_XDECREF(gca); | |||
|
1639 | Py_XDECREF(ret); | |||
|
1640 | return NULL; | |||
|
1641 | } | |||
|
1642 | ||||
|
1643 | /* | |||
1547 | * Invalidate any trie entries introduced by added revs. |
|
1644 | * Invalidate any trie entries introduced by added revs. | |
1548 | */ |
|
1645 | */ | |
1549 | static void nt_invalidate_added(indexObject *self, Py_ssize_t start) |
|
1646 | static void nt_invalidate_added(indexObject *self, Py_ssize_t start) | |
@@ -1787,6 +1884,9 b' static PyMappingMethods index_mapping_me' | |||||
1787 | static PyMethodDef index_methods[] = { |
|
1884 | static PyMethodDef index_methods[] = { | |
1788 | {"ancestors", (PyCFunction)index_ancestors, METH_VARARGS, |
|
1885 | {"ancestors", (PyCFunction)index_ancestors, METH_VARARGS, | |
1789 | "return the gca set of the given revs"}, |
|
1886 | "return the gca set of the given revs"}, | |
|
1887 | {"commonancestorsheads", (PyCFunction)index_commonancestorsheads, | |||
|
1888 | METH_VARARGS, | |||
|
1889 | "return the heads of the common ancestors of the given revs"}, | |||
1790 | {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS, |
|
1890 | {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS, | |
1791 | "clear the index caches"}, |
|
1891 | "clear the index caches"}, | |
1792 | {"get", (PyCFunction)index_m_get, METH_VARARGS, |
|
1892 | {"get", (PyCFunction)index_m_get, METH_VARARGS, |
General Comments 0
You need to be logged in to leave comments.
Login now