78 */ |
79 */ |
79 struct indexObjectStruct { |
80 struct indexObjectStruct { |
80 PyObject_HEAD |
81 PyObject_HEAD |
81 /* Type-specific fields go here. */ |
82 /* Type-specific fields go here. */ |
82 PyObject *data; /* raw bytes of index */ |
83 PyObject *data; /* raw bytes of index */ |
|
84 Py_ssize_t nodelen; /* digest size of the hash, 20 for SHA-1 */ |
|
85 PyObject *nullentry; /* fast path for references to null */ |
83 Py_buffer buf; /* buffer of data */ |
86 Py_buffer buf; /* buffer of data */ |
84 const char **offsets; /* populated on demand */ |
87 const char **offsets; /* populated on demand */ |
85 Py_ssize_t length; /* current on-disk number of elements */ |
88 Py_ssize_t length; /* current on-disk number of elements */ |
86 unsigned new_length; /* number of added elements */ |
89 unsigned new_length; /* number of added elements */ |
87 unsigned added_length; /* space reserved for added elements */ |
90 unsigned added_length; /* space reserved for added elements */ |
99 static Py_ssize_t index_length(const indexObject *self) |
102 static Py_ssize_t index_length(const indexObject *self) |
100 { |
103 { |
101 return self->length + self->new_length; |
104 return self->length + self->new_length; |
102 } |
105 } |
103 |
106 |
104 static PyObject *nullentry = NULL; |
107 static const char nullid[32] = {0}; |
105 static const char nullid[20] = {0}; |
|
106 static const Py_ssize_t nullrev = -1; |
108 static const Py_ssize_t nullrev = -1; |
107 |
109 |
108 static Py_ssize_t inline_scan(indexObject *self, const char **offsets); |
110 static Py_ssize_t inline_scan(indexObject *self, const char **offsets); |
109 |
111 |
110 static int index_find_node(indexObject *self, const char *node, |
112 static int index_find_node(indexObject *self, const char *node); |
111 Py_ssize_t nodelen); |
|
112 |
113 |
113 #if LONG_MAX == 0x7fffffffL |
114 #if LONG_MAX == 0x7fffffffL |
114 static const char *const tuple_format = PY23("Kiiiiiis#", "Kiiiiiiy#"); |
115 static const char *const tuple_format = PY23("Kiiiiiis#", "Kiiiiiiy#"); |
115 #else |
116 #else |
116 static const char *const tuple_format = PY23("kiiiiiis#", "kiiiiiiy#"); |
117 static const char *const tuple_format = PY23("kiiiiiis#", "kiiiiiiy#"); |
272 * 4 bytes: uncompressed length |
273 * 4 bytes: uncompressed length |
273 * 4 bytes: base revision |
274 * 4 bytes: base revision |
274 * 4 bytes: link revision |
275 * 4 bytes: link revision |
275 * 4 bytes: parent 1 revision |
276 * 4 bytes: parent 1 revision |
276 * 4 bytes: parent 2 revision |
277 * 4 bytes: parent 2 revision |
277 * 32 bytes: nodeid (only 20 bytes used) |
278 * 32 bytes: nodeid (only 20 bytes used with SHA-1) |
278 */ |
279 */ |
279 static PyObject *index_get(indexObject *self, Py_ssize_t pos) |
280 static PyObject *index_get(indexObject *self, Py_ssize_t pos) |
280 { |
281 { |
281 uint64_t offset_flags; |
282 uint64_t offset_flags; |
282 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; |
283 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; |
283 const char *c_node_id; |
284 const char *c_node_id; |
284 const char *data; |
285 const char *data; |
285 Py_ssize_t length = index_length(self); |
286 Py_ssize_t length = index_length(self); |
286 |
287 |
287 if (pos == nullrev) { |
288 if (pos == nullrev) { |
288 Py_INCREF(nullentry); |
289 Py_INCREF(self->nullentry); |
289 return nullentry; |
290 return self->nullentry; |
290 } |
291 } |
291 |
292 |
292 if (pos < 0 || pos >= length) { |
293 if (pos < 0 || pos >= length) { |
293 PyErr_SetString(PyExc_IndexError, "revlog index out of range"); |
294 PyErr_SetString(PyExc_IndexError, "revlog index out of range"); |
294 return NULL; |
295 return NULL; |
318 parent_2 = getbe32(data + 28); |
319 parent_2 = getbe32(data + 28); |
319 c_node_id = data + 32; |
320 c_node_id = data + 32; |
320 |
321 |
321 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, |
322 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, |
322 base_rev, link_rev, parent_1, parent_2, c_node_id, |
323 base_rev, link_rev, parent_1, parent_2, c_node_id, |
323 (Py_ssize_t)20); |
324 self->nodelen); |
324 } |
325 } |
325 |
326 |
326 /* |
327 /* |
327 * Return the 20-byte SHA of the node corresponding to the given rev. |
328 * Return the hash of node corresponding to the given rev. |
328 */ |
329 */ |
329 static const char *index_node(indexObject *self, Py_ssize_t pos) |
330 static const char *index_node(indexObject *self, Py_ssize_t pos) |
330 { |
331 { |
331 Py_ssize_t length = index_length(self); |
332 Py_ssize_t length = index_length(self); |
332 const char *data; |
333 const char *data; |
340 data = index_deref(self, pos); |
341 data = index_deref(self, pos); |
341 return data ? data + 32 : NULL; |
342 return data ? data + 32 : NULL; |
342 } |
343 } |
343 |
344 |
344 /* |
345 /* |
345 * Return the 20-byte SHA of the node corresponding to the given rev. The |
346 * Return the hash of the node corresponding to the given rev. The |
346 * rev is assumed to be existing. If not, an exception is set. |
347 * rev is assumed to be existing. If not, an exception is set. |
347 */ |
348 */ |
348 static const char *index_node_existing(indexObject *self, Py_ssize_t pos) |
349 static const char *index_node_existing(indexObject *self, Py_ssize_t pos) |
349 { |
350 { |
350 const char *node = index_node(self, pos); |
351 const char *node = index_node(self, pos); |
355 return node; |
356 return node; |
356 } |
357 } |
357 |
358 |
358 static int nt_insert(nodetree *self, const char *node, int rev); |
359 static int nt_insert(nodetree *self, const char *node, int rev); |
359 |
360 |
360 static int node_check(PyObject *obj, char **node) |
361 static int node_check(Py_ssize_t nodelen, PyObject *obj, char **node) |
361 { |
362 { |
362 Py_ssize_t nodelen; |
363 Py_ssize_t thisnodelen; |
363 if (PyBytes_AsStringAndSize(obj, node, &nodelen) == -1) |
364 if (PyBytes_AsStringAndSize(obj, node, &thisnodelen) == -1) |
364 return -1; |
365 return -1; |
365 if (nodelen == 20) |
366 if (nodelen == thisnodelen) |
366 return 0; |
367 return 0; |
367 PyErr_SetString(PyExc_ValueError, "20-byte hash required"); |
368 PyErr_Format(PyExc_ValueError, "node len %zd != expected node len %zd", |
|
369 thisnodelen, nodelen); |
368 return -1; |
370 return -1; |
369 } |
371 } |
370 |
372 |
371 static PyObject *index_append(indexObject *self, PyObject *obj) |
373 static PyObject *index_append(indexObject *self, PyObject *obj) |
372 { |
374 { |
380 &uncomp_len, &base_rev, &link_rev, &parent_1, |
382 &uncomp_len, &base_rev, &link_rev, &parent_1, |
381 &parent_2, &c_node_id, &c_node_id_len)) { |
383 &parent_2, &c_node_id, &c_node_id_len)) { |
382 PyErr_SetString(PyExc_TypeError, "8-tuple required"); |
384 PyErr_SetString(PyExc_TypeError, "8-tuple required"); |
383 return NULL; |
385 return NULL; |
384 } |
386 } |
385 if (c_node_id_len != 20 && c_node_id_len != 32) { |
387 if (c_node_id_len != self->nodelen) { |
386 PyErr_SetString(PyExc_TypeError, "invalid node"); |
388 PyErr_SetString(PyExc_TypeError, "invalid node"); |
387 return NULL; |
389 return NULL; |
388 } |
390 } |
389 |
391 |
390 if (self->new_length == self->added_length) { |
392 if (self->new_length == self->added_length) { |
695 } |
697 } |
696 iterator = PyObject_GetIter(roots); |
698 iterator = PyObject_GetIter(roots); |
697 if (iterator == NULL) |
699 if (iterator == NULL) |
698 return -2; |
700 return -2; |
699 while ((item = PyIter_Next(iterator))) { |
701 while ((item = PyIter_Next(iterator))) { |
700 if (node_check(item, &node) == -1) |
702 if (node_check(self->nodelen, item, &node) == -1) |
701 goto failed; |
703 goto failed; |
702 rev = index_find_node(self, node, 20); |
704 rev = index_find_node(self, node); |
703 /* null is implicitly public, so negative is invalid */ |
705 /* null is implicitly public, so negative is invalid */ |
704 if (rev < 0 || rev >= len) |
706 if (rev < 0 || rev >= len) |
705 goto failed; |
707 goto failed; |
706 phases[rev] = phase; |
708 phases[rev] = phase; |
707 if (minrev == -1 || minrev > rev) |
709 if (minrev == -1 || minrev > rev) |
1491 int hex) |
1493 int hex) |
1492 { |
1494 { |
1493 int (*getnybble)(const char *, Py_ssize_t) = hex ? hexdigit : nt_level; |
1495 int (*getnybble)(const char *, Py_ssize_t) = hex ? hexdigit : nt_level; |
1494 int level, maxlevel, off; |
1496 int level, maxlevel, off; |
1495 |
1497 |
1496 if (nodelen == 20 && node[0] == '\0' && memcmp(node, nullid, 20) == 0) |
1498 /* If the input is binary, do a fast check for the nullid first. */ |
|
1499 if (!hex && nodelen == self->nodelen && node[0] == '\0' && |
|
1500 node[1] == '\0' && memcmp(node, nullid, self->nodelen) == 0) |
1497 return -1; |
1501 return -1; |
1498 |
1502 |
1499 if (hex) |
1503 if (hex) |
1500 maxlevel = nodelen > 40 ? 40 : (int)nodelen; |
1504 maxlevel = nodelen; |
1501 else |
1505 else |
1502 maxlevel = nodelen > 20 ? 40 : ((int)nodelen * 2); |
1506 maxlevel = 2 * nodelen; |
|
1507 if (maxlevel > 2 * self->nodelen) |
|
1508 maxlevel = 2 * self->nodelen; |
1503 |
1509 |
1504 for (level = off = 0; level < maxlevel; level++) { |
1510 for (level = off = 0; level < maxlevel; level++) { |
1505 int k = getnybble(node, level); |
1511 int k = getnybble(node, level); |
1506 nodetreenode *n = &self->nodes[off]; |
1512 nodetreenode *n = &self->nodes[off]; |
1507 int v = n->children[k]; |
1513 int v = n->children[k]; |
1555 static int nt_insert(nodetree *self, const char *node, int rev) |
1561 static int nt_insert(nodetree *self, const char *node, int rev) |
1556 { |
1562 { |
1557 int level = 0; |
1563 int level = 0; |
1558 int off = 0; |
1564 int off = 0; |
1559 |
1565 |
1560 while (level < 40) { |
1566 while (level < 2 * self->nodelen) { |
1561 int k = nt_level(node, level); |
1567 int k = nt_level(node, level); |
1562 nodetreenode *n; |
1568 nodetreenode *n; |
1563 int v; |
1569 int v; |
1564 |
1570 |
1565 n = &self->nodes[off]; |
1571 n = &self->nodes[off]; |
1574 index_node_existing(self->index, -(v + 2)); |
1580 index_node_existing(self->index, -(v + 2)); |
1575 int noff; |
1581 int noff; |
1576 |
1582 |
1577 if (oldnode == NULL) |
1583 if (oldnode == NULL) |
1578 return -1; |
1584 return -1; |
1579 if (!memcmp(oldnode, node, 20)) { |
1585 if (!memcmp(oldnode, node, self->nodelen)) { |
1580 n->children[k] = -rev - 2; |
1586 n->children[k] = -rev - 2; |
1581 return 0; |
1587 return 0; |
1582 } |
1588 } |
1583 noff = nt_new(self); |
1589 noff = nt_new(self); |
1584 if (noff == -1) |
1590 if (noff == -1) |
1632 |
1638 |
1633 self->index = index; |
1639 self->index = index; |
1634 /* The input capacity is in terms of revisions, while the field is in |
1640 /* The input capacity is in terms of revisions, while the field is in |
1635 * terms of nodetree nodes. */ |
1641 * terms of nodetree nodes. */ |
1636 self->capacity = (capacity < 4 ? 4 : capacity / 2); |
1642 self->capacity = (capacity < 4 ? 4 : capacity / 2); |
|
1643 self->nodelen = index->nodelen; |
1637 self->depth = 0; |
1644 self->depth = 0; |
1638 self->splits = 0; |
1645 self->splits = 0; |
1639 if ((size_t)self->capacity > INT_MAX / sizeof(nodetreenode)) { |
1646 if ((size_t)self->capacity > INT_MAX / sizeof(nodetreenode)) { |
1640 PyErr_SetString(PyExc_ValueError, "overflow in init_nt"); |
1647 PyErr_SetString(PyExc_ValueError, "overflow in init_nt"); |
1641 return -1; |
1648 return -1; |
1676 */ |
1683 */ |
1677 static int nt_shortest(nodetree *self, const char *node) |
1684 static int nt_shortest(nodetree *self, const char *node) |
1678 { |
1685 { |
1679 int level, off; |
1686 int level, off; |
1680 |
1687 |
1681 for (level = off = 0; level < 40; level++) { |
1688 for (level = off = 0; level < 2 * self->nodelen; level++) { |
1682 int k, v; |
1689 int k, v; |
1683 nodetreenode *n = &self->nodes[off]; |
1690 nodetreenode *n = &self->nodes[off]; |
1684 k = nt_level(node, level); |
1691 k = nt_level(node, level); |
1685 v = n->children[k]; |
1692 v = n->children[k]; |
1686 if (v < 0) { |
1693 if (v < 0) { |
1687 const char *n; |
1694 const char *n; |
1688 v = -(v + 2); |
1695 v = -(v + 2); |
1689 n = index_node_existing(self->index, v); |
1696 n = index_node_existing(self->index, v); |
1690 if (n == NULL) |
1697 if (n == NULL) |
1691 return -3; |
1698 return -3; |
1692 if (memcmp(node, n, 20) != 0) |
1699 if (memcmp(node, n, self->nodelen) != 0) |
1693 /* |
1700 /* |
1694 * Found a unique prefix, but it wasn't for the |
1701 * Found a unique prefix, but it wasn't for the |
1695 * requested node (i.e the requested node does |
1702 * requested node (i.e the requested node does |
1696 * not exist). |
1703 * not exist). |
1697 */ |
1704 */ |
1817 * |
1824 * |
1818 * -3: error (exception set) |
1825 * -3: error (exception set) |
1819 * -2: not found (no exception set) |
1826 * -2: not found (no exception set) |
1820 * rest: valid rev |
1827 * rest: valid rev |
1821 */ |
1828 */ |
1822 static int index_find_node(indexObject *self, const char *node, |
1829 static int index_find_node(indexObject *self, const char *node) |
1823 Py_ssize_t nodelen) |
|
1824 { |
1830 { |
1825 int rev; |
1831 int rev; |
1826 |
1832 |
1827 if (index_init_nt(self) == -1) |
1833 if (index_init_nt(self) == -1) |
1828 return -3; |
1834 return -3; |
1829 |
1835 |
1830 self->ntlookups++; |
1836 self->ntlookups++; |
1831 rev = nt_find(&self->nt, node, nodelen, 0); |
1837 rev = nt_find(&self->nt, node, self->nodelen, 0); |
1832 if (rev >= -1) |
1838 if (rev >= -1) |
1833 return rev; |
1839 return rev; |
1834 |
1840 |
1835 /* |
1841 /* |
1836 * For the first handful of lookups, we scan the entire index, |
1842 * For the first handful of lookups, we scan the entire index, |
1844 if (self->ntmisses++ < 4) { |
1850 if (self->ntmisses++ < 4) { |
1845 for (rev = self->ntrev - 1; rev >= 0; rev--) { |
1851 for (rev = self->ntrev - 1; rev >= 0; rev--) { |
1846 const char *n = index_node_existing(self, rev); |
1852 const char *n = index_node_existing(self, rev); |
1847 if (n == NULL) |
1853 if (n == NULL) |
1848 return -3; |
1854 return -3; |
1849 if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) { |
1855 if (memcmp(node, n, self->nodelen) == 0) { |
1850 if (nt_insert(&self->nt, n, rev) == -1) |
1856 if (nt_insert(&self->nt, n, rev) == -1) |
1851 return -3; |
1857 return -3; |
1852 break; |
1858 break; |
1853 } |
1859 } |
1854 } |
1860 } |
1884 return NULL; |
1890 return NULL; |
1885 } |
1891 } |
1886 return index_get(self, idx); |
1892 return index_get(self, idx); |
1887 } |
1893 } |
1888 |
1894 |
1889 if (node_check(value, &node) == -1) |
1895 if (node_check(self->nodelen, value, &node) == -1) |
1890 return NULL; |
1896 return NULL; |
1891 rev = index_find_node(self, node, 20); |
1897 rev = index_find_node(self, node); |
1892 if (rev >= -1) |
1898 if (rev >= -1) |
1893 return PyInt_FromLong(rev); |
1899 return PyInt_FromLong(rev); |
1894 if (rev == -2) |
1900 if (rev == -2) |
1895 raise_revlog_error(); |
1901 raise_revlog_error(); |
1896 return NULL; |
1902 return NULL; |
1954 raise_revlog_error(); |
1960 raise_revlog_error(); |
1955 return NULL; |
1961 return NULL; |
1956 case -2: |
1962 case -2: |
1957 Py_RETURN_NONE; |
1963 Py_RETURN_NONE; |
1958 case -1: |
1964 case -1: |
1959 return PyBytes_FromStringAndSize(nullid, 20); |
1965 return PyBytes_FromStringAndSize(nullid, self->nodelen); |
1960 } |
1966 } |
1961 |
1967 |
1962 fullnode = index_node_existing(self, rev); |
1968 fullnode = index_node_existing(self, rev); |
1963 if (fullnode == NULL) { |
1969 if (fullnode == NULL) { |
1964 return NULL; |
1970 return NULL; |
1965 } |
1971 } |
1966 return PyBytes_FromStringAndSize(fullnode, 20); |
1972 return PyBytes_FromStringAndSize(fullnode, self->nodelen); |
1967 } |
1973 } |
1968 |
1974 |
1969 static PyObject *index_shortest(indexObject *self, PyObject *args) |
1975 static PyObject *index_shortest(indexObject *self, PyObject *args) |
1970 { |
1976 { |
1971 PyObject *val; |
1977 PyObject *val; |
1972 char *node; |
1978 char *node; |
1973 int length; |
1979 int length; |
1974 |
1980 |
1975 if (!PyArg_ParseTuple(args, "O", &val)) |
1981 if (!PyArg_ParseTuple(args, "O", &val)) |
1976 return NULL; |
1982 return NULL; |
1977 if (node_check(val, &node) == -1) |
1983 if (node_check(self->nodelen, val, &node) == -1) |
1978 return NULL; |
1984 return NULL; |
1979 |
1985 |
1980 self->ntlookups++; |
1986 self->ntlookups++; |
1981 if (index_init_nt(self) == -1) |
1987 if (index_init_nt(self) == -1) |
1982 return NULL; |
1988 return NULL; |
1998 char *node; |
2004 char *node; |
1999 int rev; |
2005 int rev; |
2000 |
2006 |
2001 if (!PyArg_ParseTuple(args, "O", &val)) |
2007 if (!PyArg_ParseTuple(args, "O", &val)) |
2002 return NULL; |
2008 return NULL; |
2003 if (node_check(val, &node) == -1) |
2009 if (node_check(self->nodelen, val, &node) == -1) |
2004 return NULL; |
2010 return NULL; |
2005 rev = index_find_node(self, node, 20); |
2011 rev = index_find_node(self, node); |
2006 if (rev == -3) |
2012 if (rev == -3) |
2007 return NULL; |
2013 return NULL; |
2008 if (rev == -2) |
2014 if (rev == -2) |
2009 Py_RETURN_NONE; |
2015 Py_RETURN_NONE; |
2010 return PyInt_FromLong(rev); |
2016 return PyInt_FromLong(rev); |
2046 static PyObject *index_m_rev(indexObject *self, PyObject *val) |
2052 static PyObject *index_m_rev(indexObject *self, PyObject *val) |
2047 { |
2053 { |
2048 char *node; |
2054 char *node; |
2049 int rev; |
2055 int rev; |
2050 |
2056 |
2051 if (node_check(val, &node) == -1) |
2057 if (node_check(self->nodelen, val, &node) == -1) |
2052 return NULL; |
2058 return NULL; |
2053 rev = index_find_node(self, node, 20); |
2059 rev = index_find_node(self, node); |
2054 if (rev >= -1) |
2060 if (rev >= -1) |
2055 return PyInt_FromLong(rev); |
2061 return PyInt_FromLong(rev); |
2056 if (rev == -2) |
2062 if (rev == -2) |
2057 raise_revlog_error(); |
2063 raise_revlog_error(); |
2058 return NULL; |
2064 return NULL; |
2527 long rev; |
2533 long rev; |
2528 |
2534 |
2529 if (PySlice_Check(item) && value == NULL) |
2535 if (PySlice_Check(item) && value == NULL) |
2530 return index_slice_del(self, item); |
2536 return index_slice_del(self, item); |
2531 |
2537 |
2532 if (node_check(item, &node) == -1) |
2538 if (node_check(self->nodelen, item, &node) == -1) |
2533 return -1; |
2539 return -1; |
2534 |
2540 |
2535 if (value == NULL) |
2541 if (value == NULL) |
2536 return self->ntinitialized ? nt_delete_node(&self->nt, node) |
2542 return self->ntinitialized ? nt_delete_node(&self->nt, node) |
2537 : 0; |
2543 : 0; |
2594 self->headrevs = NULL; |
2600 self->headrevs = NULL; |
2595 self->filteredrevs = Py_None; |
2601 self->filteredrevs = Py_None; |
2596 Py_INCREF(Py_None); |
2602 Py_INCREF(Py_None); |
2597 self->ntinitialized = 0; |
2603 self->ntinitialized = 0; |
2598 self->offsets = NULL; |
2604 self->offsets = NULL; |
|
2605 self->nodelen = 20; |
|
2606 self->nullentry = NULL; |
2599 |
2607 |
2600 if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj)) |
2608 if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj)) |
2601 return -1; |
2609 return -1; |
2602 if (!PyObject_CheckBuffer(data_obj)) { |
2610 if (!PyObject_CheckBuffer(data_obj)) { |
2603 PyErr_SetString(PyExc_TypeError, |
2611 PyErr_SetString(PyExc_TypeError, |
2604 "data does not support buffer interface"); |
2612 "data does not support buffer interface"); |
2605 return -1; |
2613 return -1; |
2606 } |
2614 } |
|
2615 if (self->nodelen < 20 || self->nodelen > sizeof(nullid)) { |
|
2616 PyErr_SetString(PyExc_RuntimeError, "unsupported node size"); |
|
2617 return -1; |
|
2618 } |
|
2619 |
|
2620 self->nullentry = Py_BuildValue(PY23("iiiiiiis#", "iiiiiiiy#"), 0, 0, 0, |
|
2621 -1, -1, -1, -1, nullid, self->nodelen); |
|
2622 if (!self->nullentry) |
|
2623 return -1; |
|
2624 PyObject_GC_UnTrack(self->nullentry); |
2607 |
2625 |
2608 if (PyObject_GetBuffer(data_obj, &self->buf, PyBUF_SIMPLE) == -1) |
2626 if (PyObject_GetBuffer(data_obj, &self->buf, PyBUF_SIMPLE) == -1) |
2609 return -1; |
2627 return -1; |
2610 size = self->buf.len; |
2628 size = self->buf.len; |
2611 |
2629 |
2669 PyBuffer_Release(&self->buf); |
2687 PyBuffer_Release(&self->buf); |
2670 memset(&self->buf, 0, sizeof(self->buf)); |
2688 memset(&self->buf, 0, sizeof(self->buf)); |
2671 } |
2689 } |
2672 Py_XDECREF(self->data); |
2690 Py_XDECREF(self->data); |
2673 PyMem_Free(self->added); |
2691 PyMem_Free(self->added); |
|
2692 Py_XDECREF(self->nullentry); |
2674 PyObject_Del(self); |
2693 PyObject_Del(self); |
2675 } |
2694 } |
2676 |
2695 |
2677 static PySequenceMethods index_sequence_methods = { |
2696 static PySequenceMethods index_sequence_methods = { |
2678 (lenfunc)index_length, /* sq_length */ |
2697 (lenfunc)index_length, /* sq_length */ |
2839 if (PyType_Ready(&nodetreeType) < 0) |
2858 if (PyType_Ready(&nodetreeType) < 0) |
2840 return; |
2859 return; |
2841 Py_INCREF(&nodetreeType); |
2860 Py_INCREF(&nodetreeType); |
2842 PyModule_AddObject(mod, "nodetree", (PyObject *)&nodetreeType); |
2861 PyModule_AddObject(mod, "nodetree", (PyObject *)&nodetreeType); |
2843 |
2862 |
2844 if (!nullentry) { |
|
2845 nullentry = |
|
2846 Py_BuildValue(PY23("iiiiiiis#", "iiiiiiiy#"), 0, 0, 0, -1, |
|
2847 -1, -1, -1, nullid, (Py_ssize_t)20); |
|
2848 } |
|
2849 if (nullentry) |
|
2850 PyObject_GC_UnTrack(nullentry); |
|
2851 |
|
2852 caps = PyCapsule_New(&CAPI, "mercurial.cext.parsers.revlog_CAPI", NULL); |
2863 caps = PyCapsule_New(&CAPI, "mercurial.cext.parsers.revlog_CAPI", NULL); |
2853 if (caps != NULL) |
2864 if (caps != NULL) |
2854 PyModule_AddObject(mod, "revlog_CAPI", caps); |
2865 PyModule_AddObject(mod, "revlog_CAPI", caps); |
2855 } |
2866 } |