annotate mercurial/parsers.c @ 20750:d4f2f2d74210

revset: changed spanset to extend _orderedsetmixin Now spanset can use the lazy min and max methods implementation.
author Lucas Moscovicz <lmoscovicz@fb.com>
date Thu, 13 Mar 2014 11:36:11 -0700
parents 3681de20b0a7
children e286ab22e461
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1 /*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2 parsers.c - efficient content parsing
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
3
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 Copyright 2008 Matt Mackall <mpm@selenic.com> and others
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
6 This software may be used and distributed according to the terms of
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7 the GNU General Public License, incorporated herein by reference.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8 */
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
9
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 #include <Python.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 #include <ctype.h>
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
12 #include <stddef.h>
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
13 #include <string.h>
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
15 #include "util.h"
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
16
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
17 static char *versionerrortext = "Python minor version mismatch";
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
18
19718
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
19 static int8_t hextable[256] = {
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
20 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
21 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
22 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
23 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 0-9 */
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
24 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A-F */
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
25 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
26 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* a-f */
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
27 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
28 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
29 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
30 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
34 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
36 };
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
37
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
38 static inline int hexdigit(const char *p, Py_ssize_t off)
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39 {
19718
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
40 int8_t val = hextable[(unsigned char)p[off]];
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
41
19718
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
42 if (val >= 0) {
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
43 return val;
d69e06724b96 parsers: use a lookup table to convert hex to binary
Siddharth Agarwal <sid0@fb.com>
parents: 19652
diff changeset
44 }
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
46 PyErr_SetString(PyExc_ValueError, "input contains non-hex character");
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
47 return 0;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 }
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 /*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 * Turn a hex-encoded string into binary.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 */
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 static PyObject *unhexlify(const char *str, int len)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 {
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
55 PyObject *ret;
6395
3f0294536b24 fix const annotation warning
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6389
diff changeset
56 char *d;
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
57 int i;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
59 ret = PyBytes_FromStringAndSize(NULL, len / 2);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
60
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
61 if (!ret)
7092
fb3fc27617a2 parsers: speed up hex decoding for manifests
Matt Mackall <mpm@selenic.com>
parents: 7091
diff changeset
62 return NULL;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
64 d = PyBytes_AsString(ret);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
65
16617
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
66 for (i = 0; i < len;) {
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
67 int hi = hexdigit(str, i++);
4fb16743049d parsers: change the type signature of hexdigit
Bryan O'Sullivan <bryano@fb.com>
parents: 16616
diff changeset
68 int lo = hexdigit(str, i++);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69 *d++ = (hi << 4) | lo;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 }
7091
12b35ae03365 parsers: clean up whitespace
Matt Mackall <mpm@selenic.com>
parents: 6395
diff changeset
71
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 return ret;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 }
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 /*
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76 * This code assumes that a manifest is stitched together with newline
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 * ('\n') characters.
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 */
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 static PyObject *parse_manifest(PyObject *self, PyObject *args)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
81 PyObject *mfdict, *fdict;
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
82 char *str, *start, *end;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83 int len;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
84
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85 if (!PyArg_ParseTuple(args, "O!O!s#:parse_manifest",
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86 &PyDict_Type, &mfdict,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 &PyDict_Type, &fdict,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 &str, &len))
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
89 goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
91 start = str;
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
92 end = str + len;
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
93 while (start < end) {
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
94 PyObject *file = NULL, *node = NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
95 PyObject *flags = NULL;
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
96 char *zero = NULL, *newline = NULL;
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
97 ptrdiff_t nlen;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
99 zero = memchr(start, '\0', end - start);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
100 if (!zero) {
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101 PyErr_SetString(PyExc_ValueError,
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102 "manifest entry has no separator");
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
103 goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
104 }
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
106 newline = memchr(zero + 1, '\n', end - (zero + 1));
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
107 if (!newline) {
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
108 PyErr_SetString(PyExc_ValueError,
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
109 "manifest contains trailing garbage");
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
110 goto quit;
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
111 }
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
112
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
113 file = PyBytes_FromStringAndSize(start, zero - start);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
114
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
115 if (!file)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116 goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
117
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
118 nlen = newline - zero - 1;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
119
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
120 node = unhexlify(zero + 1, nlen > 40 ? 40 : (int)nlen);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
121 if (!node)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
122 goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
123
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
124 if (nlen > 40) {
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
125 flags = PyBytes_FromStringAndSize(zero + 41,
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
126 nlen - 40);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
127 if (!flags)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
128 goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
129
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
130 if (PyDict_SetItem(fdict, file, flags) == -1)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
131 goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
132 }
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
133
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
134 if (PyDict_SetItem(mfdict, file, node) == -1)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
135 goto bail;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
136
19728
3daabd2da78b parse_manifest: rewrite to use memchr
Siddharth Agarwal <sid0@fb.com>
parents: 19727
diff changeset
137 start = newline + 1;
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
138
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139 Py_XDECREF(flags);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
140 Py_XDECREF(node);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
141 Py_XDECREF(file);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
142 continue;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
143 bail:
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
144 Py_XDECREF(flags);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
145 Py_XDECREF(node);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
146 Py_XDECREF(file);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
147 goto quit;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
148 }
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
149
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
150 Py_INCREF(Py_None);
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
151 return Py_None;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
152 quit:
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
153 return NULL;
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
154 }
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
155
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
156 static PyObject *parse_dirstate(PyObject *self, PyObject *args)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
157 {
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
158 PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
159 PyObject *fname = NULL, *cname = NULL, *entry = NULL;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
160 char state, *cur, *str, *cpos;
19725
5e25d71a58cc parsers: state is a char, not an int
Bryan O'Sullivan <bryano@fb.com>
parents: 19718
diff changeset
161 int mode, size, mtime;
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
162 unsigned int flen;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
163 int len, pos = 40;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
164
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
165 if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
166 &PyDict_Type, &dmap,
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
167 &PyDict_Type, &cmap,
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
168 &str, &len))
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
169 goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
170
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
171 /* read parents */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
172 if (len < 40)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
173 goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
174
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
175 parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
176 if (!parents)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
177 goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
178
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
179 /* read filenames */
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
180 while (pos >= 40 && pos < len) {
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
181 cur = str + pos;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
182 /* unpack header */
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
183 state = *cur;
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
184 mode = getbe32(cur + 1);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
185 size = getbe32(cur + 5);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
186 mtime = getbe32(cur + 9);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
187 flen = getbe32(cur + 13);
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
188 pos += 17;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
189 cur += 17;
20316
40f08c31844c parsers: fix 'unsigned expression is always true' warning (issue4142)
David Soria Parra <davidsp@fb.com>
parents: 20169
diff changeset
190 if (flen > len - pos) {
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
191 PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
192 goto quit;
7174
4da87407b845 parsers.c: fix integer overflows
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7168
diff changeset
193 }
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
194
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
195 entry = Py_BuildValue("ciii", state, mode, size, mtime);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
196 if (!entry)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
197 goto quit;
7175
5d8626b2c1db parsers.c: do not try to untrack after a failure
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7174
diff changeset
198 PyObject_GC_UnTrack(entry); /* don't waste time with this */
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
199
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
200 cpos = memchr(cur, 0, flen);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
201 if (cpos) {
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
202 fname = PyBytes_FromStringAndSize(cur, cpos - cur);
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
203 cname = PyBytes_FromStringAndSize(cpos + 1,
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
204 flen - (cpos - cur) - 1);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
205 if (!fname || !cname ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
206 PyDict_SetItem(cmap, fname, cname) == -1 ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
207 PyDict_SetItem(dmap, fname, entry) == -1)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
208 goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
209 Py_DECREF(cname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
210 } else {
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
211 fname = PyBytes_FromStringAndSize(cur, flen);
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
212 if (!fname ||
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
213 PyDict_SetItem(dmap, fname, entry) == -1)
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
214 goto quit;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
215 }
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
216 Py_DECREF(fname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
217 Py_DECREF(entry);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
218 fname = cname = entry = NULL;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
219 pos += flen;
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
220 }
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
221
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
222 ret = parents;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
223 Py_INCREF(ret);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
224 quit:
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
225 Py_XDECREF(fname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
226 Py_XDECREF(cname);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
227 Py_XDECREF(entry);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
228 Py_XDECREF(parents);
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
229 return ret;
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
230 }
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
231
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
232 static inline int getintat(PyObject *tuple, int off, uint32_t *v)
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
233 {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
234 PyObject *o = PyTuple_GET_ITEM(tuple, off);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
235 long val;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
236
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
237 if (PyInt_Check(o))
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
238 val = PyInt_AS_LONG(o);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
239 else if (PyLong_Check(o)) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
240 val = PyLong_AsLong(o);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
241 if (val == -1 && PyErr_Occurred())
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
242 return -1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
243 } else {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
244 PyErr_SetString(PyExc_TypeError, "expected an int or long");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
245 return -1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
246 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
247 if (LONG_MAX > INT_MAX && (val > INT_MAX || val < INT_MIN)) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
248 PyErr_SetString(PyExc_OverflowError,
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
249 "Python value to large to convert to uint32_t");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
250 return -1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
251 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
252 *v = (uint32_t)val;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
253 return 0;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
254 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
255
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
256 static PyObject *dirstate_unset;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
257
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
258 /*
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
259 * Efficiently pack a dirstate object into its on-disk format.
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
260 */
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
261 static PyObject *pack_dirstate(PyObject *self, PyObject *args)
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
262 {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
263 PyObject *packobj = NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
264 PyObject *map, *copymap, *pl;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
265 Py_ssize_t nbytes, pos, l;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
266 PyObject *k, *v, *pn;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
267 char *p, *s;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
268 double now;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
269
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
270 if (!PyArg_ParseTuple(args, "O!O!Od:pack_dirstate",
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
271 &PyDict_Type, &map, &PyDict_Type, &copymap,
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
272 &pl, &now))
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
273 return NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
274
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
275 if (!PySequence_Check(pl) || PySequence_Size(pl) != 2) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
276 PyErr_SetString(PyExc_TypeError, "expected 2-element sequence");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
277 return NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
278 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
279
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
280 /* Figure out how much we need to allocate. */
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
281 for (nbytes = 40, pos = 0; PyDict_Next(map, &pos, &k, &v);) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
282 PyObject *c;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
283 if (!PyString_Check(k)) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
284 PyErr_SetString(PyExc_TypeError, "expected string key");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
285 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
286 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
287 nbytes += PyString_GET_SIZE(k) + 17;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
288 c = PyDict_GetItem(copymap, k);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
289 if (c) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
290 if (!PyString_Check(c)) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
291 PyErr_SetString(PyExc_TypeError,
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
292 "expected string key");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
293 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
294 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
295 nbytes += PyString_GET_SIZE(c) + 1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
296 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
297 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
298
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
299 packobj = PyString_FromStringAndSize(NULL, nbytes);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
300 if (packobj == NULL)
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
301 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
302
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
303 p = PyString_AS_STRING(packobj);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
304
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
305 pn = PySequence_ITEM(pl, 0);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
306 if (PyString_AsStringAndSize(pn, &s, &l) == -1 || l != 20) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
307 PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
308 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
309 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
310 memcpy(p, s, l);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
311 p += 20;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
312 pn = PySequence_ITEM(pl, 1);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
313 if (PyString_AsStringAndSize(pn, &s, &l) == -1 || l != 20) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
314 PyErr_SetString(PyExc_TypeError, "expected a 20-byte hash");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
315 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
316 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
317 memcpy(p, s, l);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
318 p += 20;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
319
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
320 for (pos = 0; PyDict_Next(map, &pos, &k, &v); ) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
321 uint32_t mode, size, mtime;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
322 Py_ssize_t len, l;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
323 PyObject *o;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
324 char *s, *t;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
325
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
326 if (!PyTuple_Check(v) || PyTuple_GET_SIZE(v) != 4) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
327 PyErr_SetString(PyExc_TypeError, "expected a 4-tuple");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
328 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
329 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
330 o = PyTuple_GET_ITEM(v, 0);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
331 if (PyString_AsStringAndSize(o, &s, &l) == -1 || l != 1) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
332 PyErr_SetString(PyExc_TypeError, "expected one byte");
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
333 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
334 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
335 *p++ = *s;
17165
249cc4ec4327 parsers.c: remove warning: 'size' may be used uninitialized in this function
Mads Kiilerich <mads@kiilerich.com>
parents: 16955
diff changeset
336 if (getintat(v, 1, &mode) == -1)
249cc4ec4327 parsers.c: remove warning: 'size' may be used uninitialized in this function
Mads Kiilerich <mads@kiilerich.com>
parents: 16955
diff changeset
337 goto bail;
249cc4ec4327 parsers.c: remove warning: 'size' may be used uninitialized in this function
Mads Kiilerich <mads@kiilerich.com>
parents: 16955
diff changeset
338 if (getintat(v, 2, &size) == -1)
249cc4ec4327 parsers.c: remove warning: 'size' may be used uninitialized in this function
Mads Kiilerich <mads@kiilerich.com>
parents: 16955
diff changeset
339 goto bail;
249cc4ec4327 parsers.c: remove warning: 'size' may be used uninitialized in this function
Mads Kiilerich <mads@kiilerich.com>
parents: 16955
diff changeset
340 if (getintat(v, 3, &mtime) == -1)
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
341 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
342 if (*s == 'n' && mtime == (uint32_t)now) {
18567
194e63c1ccb9 dirstate: move pure python dirstate packing to pure/parsers.py
Siddharth Agarwal <sid0@fb.com>
parents: 18504
diff changeset
343 /* See pure/parsers.py:pack_dirstate for why we do
194e63c1ccb9 dirstate: move pure python dirstate packing to pure/parsers.py
Siddharth Agarwal <sid0@fb.com>
parents: 18504
diff changeset
344 * this. */
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
345 if (PyDict_SetItem(map, k, dirstate_unset) == -1)
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
346 goto bail;
19652
187bf2dde7c1 pack_dirstate: only invalidate mtime for files written in the last second
Siddharth Agarwal <sid0@fb.com>
parents: 19504
diff changeset
347 mtime = -1;
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
348 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
349 putbe32(mode, p);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
350 putbe32(size, p + 4);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
351 putbe32(mtime, p + 8);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
352 t = p + 12;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
353 p += 16;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
354 len = PyString_GET_SIZE(k);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
355 memcpy(p, PyString_AS_STRING(k), len);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
356 p += len;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
357 o = PyDict_GetItem(copymap, k);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
358 if (o) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
359 *p++ = '\0';
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
360 l = PyString_GET_SIZE(o);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
361 memcpy(p, PyString_AS_STRING(o), l);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
362 p += l;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
363 len += l + 1;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
364 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
365 putbe32((uint32_t)len, t);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
366 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
367
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
368 pos = p - PyString_AS_STRING(packobj);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
369 if (pos != nbytes) {
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
370 PyErr_Format(PyExc_SystemError, "bad dirstate size: %ld != %ld",
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
371 (long)pos, (long)nbytes);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
372 goto bail;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
373 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
374
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
375 return packobj;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
376 bail:
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
377 Py_XDECREF(packobj);
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
378 return NULL;
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
379 }
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
380
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
381 /*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
382 * A base-16 trie for fast node->rev mapping.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
383 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
384 * Positive value is index of the next node in the trie
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
385 * Negative value is a leaf: -(rev + 1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
386 * Zero is empty
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
387 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
388 typedef struct {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
389 int children[16];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
390 } nodetree;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
391
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
392 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
393 * This class has two behaviours.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
394 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
395 * When used in a list-like way (with integer keys), we decode an
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
396 * entry in a RevlogNG index file on demand. Our last entry is a
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
397 * sentinel, always a nullid. We have limited support for
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
398 * integer-keyed insert and delete, only at elements right before the
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
399 * sentinel.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
400 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
401 * With string keys, we lazily perform a reverse mapping from node to
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
402 * rev, using a base-16 trie.
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
403 */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
404 typedef struct {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
405 PyObject_HEAD
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
406 /* Type-specific fields go here. */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
407 PyObject *data; /* raw bytes of index */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
408 PyObject **cache; /* cached tuples */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
409 const char **offsets; /* populated on demand */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
410 Py_ssize_t raw_length; /* original number of elements */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
411 Py_ssize_t length; /* current number of elements */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
412 PyObject *added; /* populated on demand */
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
413 PyObject *headrevs; /* cache, invalidated on changes */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
414 nodetree *nt; /* base-16 trie */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
415 int ntlength; /* # nodes in use */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
416 int ntcapacity; /* # nodes allocated */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
417 int ntdepth; /* maximum depth of tree */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
418 int ntsplits; /* # splits performed */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
419 int ntrev; /* last rev scanned */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
420 int ntlookups; /* # lookups */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
421 int ntmisses; /* # lookups that miss the cache */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
422 int inlined;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
423 } indexObject;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
424
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
425 static Py_ssize_t index_length(const indexObject *self)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
426 {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
427 if (self->added == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
428 return self->length;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
429 return self->length + PyList_GET_SIZE(self->added);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
430 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
431
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
432 static PyObject *nullentry;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
433 static const char nullid[20];
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
434
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
435 static long inline_scan(indexObject *self, const char **offsets);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
436
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
437 #if LONG_MAX == 0x7fffffffL
16393
ee163a9cf37c util.h: more Python 2.4 fixes
Matt Mackall <mpm@selenic.com>
parents: 16385
diff changeset
438 static char *tuple_format = "Kiiiiiis#";
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
439 #else
16393
ee163a9cf37c util.h: more Python 2.4 fixes
Matt Mackall <mpm@selenic.com>
parents: 16385
diff changeset
440 static char *tuple_format = "kiiiiiis#";
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
441 #endif
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
442
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
443 /* A RevlogNG v1 index entry is 64 bytes long. */
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
444 static const long v1_hdrsize = 64;
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
445
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
446 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
447 * Return a pointer to the beginning of a RevlogNG record.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
448 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
449 static const char *index_deref(indexObject *self, Py_ssize_t pos)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
450 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
451 if (self->inlined && pos > 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
452 if (self->offsets == NULL) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
453 self->offsets = malloc(self->raw_length *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
454 sizeof(*self->offsets));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
455 if (self->offsets == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
456 return (const char *)PyErr_NoMemory();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
457 inline_scan(self, self->offsets);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
458 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
459 return self->offsets[pos];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
460 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
461
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
462 return PyString_AS_STRING(self->data) + pos * v1_hdrsize;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
463 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
464
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
465 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
466 * RevlogNG format (all in big endian, data may be inlined):
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
467 * 6 bytes: offset
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
468 * 2 bytes: flags
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
469 * 4 bytes: compressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
470 * 4 bytes: uncompressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
471 * 4 bytes: base revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
472 * 4 bytes: link revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
473 * 4 bytes: parent 1 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
474 * 4 bytes: parent 2 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
475 * 32 bytes: nodeid (only 20 bytes used)
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
476 */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
477 static PyObject *index_get(indexObject *self, Py_ssize_t pos)
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
478 {
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
479 uint64_t offset_flags;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
480 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
481 const char *c_node_id;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
482 const char *data;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
483 Py_ssize_t length = index_length(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
484 PyObject *entry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
485
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
486 if (pos < 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
487 pos += length;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
488
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
489 if (pos < 0 || pos >= length) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
490 PyErr_SetString(PyExc_IndexError, "revlog index out of range");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
491 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
492 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
493
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
494 if (pos == length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
495 Py_INCREF(nullentry);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
496 return nullentry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
497 }
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
498
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
499 if (pos >= self->length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
500 PyObject *obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
501 obj = PyList_GET_ITEM(self->added, pos - self->length + 1);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
502 Py_INCREF(obj);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
503 return obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
504 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
505
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
506 if (self->cache) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
507 if (self->cache[pos]) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
508 Py_INCREF(self->cache[pos]);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
509 return self->cache[pos];
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
510 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
511 } else {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
512 self->cache = calloc(self->raw_length, sizeof(PyObject *));
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
513 if (self->cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
514 return PyErr_NoMemory();
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
515 }
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7186
diff changeset
516
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
517 data = index_deref(self, pos);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
518 if (data == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
519 return NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
520
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
521 offset_flags = getbe32(data + 4);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
522 if (pos == 0) /* mask out version number for the first entry */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
523 offset_flags &= 0xFFFF;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
524 else {
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
525 uint32_t offset_high = getbe32(data);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
526 offset_flags |= ((uint64_t)offset_high) << 32;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
527 }
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
528
16437
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
529 comp_len = getbe32(data + 8);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
530 uncomp_len = getbe32(data + 12);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
531 base_rev = getbe32(data + 16);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
532 link_rev = getbe32(data + 20);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
533 parent_1 = getbe32(data + 24);
d126a0d16856 util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents: 16414
diff changeset
534 parent_2 = getbe32(data + 28);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
535 c_node_id = data + 32;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
536
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
537 entry = Py_BuildValue(tuple_format, offset_flags, comp_len,
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
538 uncomp_len, base_rev, link_rev,
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
539 parent_1, parent_2, c_node_id, 20);
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
540
19726
b3c8c6f2b5c1 parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents: 19725
diff changeset
541 if (entry) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
542 PyObject_GC_UnTrack(entry);
19726
b3c8c6f2b5c1 parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents: 19725
diff changeset
543 Py_INCREF(entry);
b3c8c6f2b5c1 parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents: 19725
diff changeset
544 }
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
545
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
546 self->cache[pos] = entry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
547
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
548 return entry;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
549 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
550
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
551 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
552 * Return the 20-byte SHA of the node corresponding to the given rev.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
553 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
554 static const char *index_node(indexObject *self, Py_ssize_t pos)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
555 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
556 Py_ssize_t length = index_length(self);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
557 const char *data;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
558
16664
5bc6edf71b39 parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents: 16663
diff changeset
559 if (pos == length - 1 || pos == INT_MAX)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
560 return nullid;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
561
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
562 if (pos >= length)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
563 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
564
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
565 if (pos >= self->length - 1) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
566 PyObject *tuple, *str;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
567 tuple = PyList_GET_ITEM(self->added, pos - self->length + 1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
568 str = PyTuple_GetItem(tuple, 7);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
569 return str ? PyString_AS_STRING(str) : NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
570 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
571
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
572 data = index_deref(self, pos);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
573 return data ? data + 32 : NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
574 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
575
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
576 static int nt_insert(indexObject *self, const char *node, int rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
577
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
578 static int node_check(PyObject *obj, char **node, Py_ssize_t *nodelen)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
579 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
580 if (PyString_AsStringAndSize(obj, node, nodelen) == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
581 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
582 if (*nodelen == 20)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
583 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
584 PyErr_SetString(PyExc_ValueError, "20-byte hash required");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
585 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
586 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
587
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
588 static PyObject *index_insert(indexObject *self, PyObject *args)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
589 {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
590 PyObject *obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
591 char *node;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
592 long offset;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
593 Py_ssize_t len, nodelen;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
594
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
595 if (!PyArg_ParseTuple(args, "lO", &offset, &obj))
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
596 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
597
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
598 if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 8) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
599 PyErr_SetString(PyExc_TypeError, "8-tuple required");
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
600 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
601 }
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
602
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
603 if (node_check(PyTuple_GET_ITEM(obj, 7), &node, &nodelen) == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
604 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
605
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
606 len = index_length(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
607
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
608 if (offset < 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
609 offset += len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
610
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
611 if (offset != len - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
612 PyErr_SetString(PyExc_IndexError,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
613 "insert only supported at index -1");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
614 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
615 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
616
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
617 if (offset > INT_MAX) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
618 PyErr_SetString(PyExc_ValueError,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
619 "currently only 2**31 revs supported");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
620 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
621 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
622
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
623 if (self->added == NULL) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
624 self->added = PyList_New(0);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
625 if (self->added == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
626 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
627 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
628
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
629 if (PyList_Append(self->added, obj) == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
630 return NULL;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
631
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
632 if (self->nt)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
633 nt_insert(self, node, (int)offset);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
634
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
635 Py_CLEAR(self->headrevs);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
636 Py_RETURN_NONE;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
637 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
638
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
639 static void _index_clearcaches(indexObject *self)
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
640 {
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
641 if (self->cache) {
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
642 Py_ssize_t i;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
643
16732
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
644 for (i = 0; i < self->raw_length; i++)
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
645 Py_CLEAR(self->cache[i]);
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
646 free(self->cache);
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
647 self->cache = NULL;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
648 }
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
649 if (self->offsets) {
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
650 free(self->offsets);
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
651 self->offsets = NULL;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
652 }
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
653 if (self->nt) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
654 free(self->nt);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
655 self->nt = NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
656 }
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
657 Py_CLEAR(self->headrevs);
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
658 }
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
659
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
660 static PyObject *index_clearcaches(indexObject *self)
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
661 {
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
662 _index_clearcaches(self);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
663 self->ntlength = self->ntcapacity = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
664 self->ntdepth = self->ntsplits = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
665 self->ntrev = -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
666 self->ntlookups = self->ntmisses = 0;
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
667 Py_RETURN_NONE;
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
668 }
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
669
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
670 static PyObject *index_stats(indexObject *self)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
671 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
672 PyObject *obj = PyDict_New();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
673
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
674 if (obj == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
675 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
676
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
677 #define istat(__n, __d) \
16629
1435866c1937 parser: use PyInt_FromSsize_t in index_stats
Adrian Buehlmann <adrian@cadifra.com>
parents: 16621
diff changeset
678 if (PyDict_SetItemString(obj, __d, PyInt_FromSsize_t(self->__n)) == -1) \
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
679 goto bail;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
680
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
681 if (self->added) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
682 Py_ssize_t len = PyList_GET_SIZE(self->added);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
683 if (PyDict_SetItemString(obj, "index entries added",
16629
1435866c1937 parser: use PyInt_FromSsize_t in index_stats
Adrian Buehlmann <adrian@cadifra.com>
parents: 16621
diff changeset
684 PyInt_FromSsize_t(len)) == -1)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
685 goto bail;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
686 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
687
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
688 if (self->raw_length != self->length - 1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
689 istat(raw_length, "revs on disk");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
690 istat(length, "revs in memory");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
691 istat(ntcapacity, "node trie capacity");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
692 istat(ntdepth, "node trie depth");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
693 istat(ntlength, "node trie count");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
694 istat(ntlookups, "node trie lookups");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
695 istat(ntmisses, "node trie misses");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
696 istat(ntrev, "node trie last rev scanned");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
697 istat(ntsplits, "node trie splits");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
698
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
699 #undef istat
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
700
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
701 return obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
702
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
703 bail:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
704 Py_XDECREF(obj);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
705 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
706 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
707
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
708 /*
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
709 * When we cache a list, we want to be sure the caller can't mutate
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
710 * the cached copy.
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
711 */
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
712 static PyObject *list_copy(PyObject *list)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
713 {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
714 Py_ssize_t len = PyList_GET_SIZE(list);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
715 PyObject *newlist = PyList_New(len);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
716 Py_ssize_t i;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
717
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
718 if (newlist == NULL)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
719 return NULL;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
720
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
721 for (i = 0; i < len; i++) {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
722 PyObject *obj = PyList_GET_ITEM(list, i);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
723 Py_INCREF(obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
724 PyList_SET_ITEM(newlist, i, obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
725 }
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
726
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
727 return newlist;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
728 }
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
729
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
730 static PyObject *index_headrevs(indexObject *self)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
731 {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
732 Py_ssize_t i, len, addlen;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
733 char *nothead = NULL;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
734 PyObject *heads;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
735
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
736 if (self->headrevs)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
737 return list_copy(self->headrevs);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
738
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
739 len = index_length(self) - 1;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
740 heads = PyList_New(0);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
741 if (heads == NULL)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
742 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
743 if (len == 0) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
744 PyObject *nullid = PyInt_FromLong(-1);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
745 if (nullid == NULL || PyList_Append(heads, nullid) == -1) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
746 Py_XDECREF(nullid);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
747 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
748 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
749 goto done;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
750 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
751
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
752 nothead = calloc(len, 1);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
753 if (nothead == NULL)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
754 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
755
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
756 for (i = 0; i < self->raw_length; i++) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
757 const char *data = index_deref(self, i);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
758 int parent_1 = getbe32(data + 24);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
759 int parent_2 = getbe32(data + 28);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
760 if (parent_1 >= 0)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
761 nothead[parent_1] = 1;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
762 if (parent_2 >= 0)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
763 nothead[parent_2] = 1;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
764 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
765
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
766 addlen = self->added ? PyList_GET_SIZE(self->added) : 0;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
767
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
768 for (i = 0; i < addlen; i++) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
769 PyObject *rev = PyList_GET_ITEM(self->added, i);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
770 PyObject *p1 = PyTuple_GET_ITEM(rev, 5);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
771 PyObject *p2 = PyTuple_GET_ITEM(rev, 6);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
772 long parent_1, parent_2;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
773
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
774 if (!PyInt_Check(p1) || !PyInt_Check(p2)) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
775 PyErr_SetString(PyExc_TypeError,
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
776 "revlog parents are invalid");
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
777 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
778 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
779 parent_1 = PyInt_AS_LONG(p1);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
780 parent_2 = PyInt_AS_LONG(p2);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
781 if (parent_1 >= 0)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
782 nothead[parent_1] = 1;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
783 if (parent_2 >= 0)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
784 nothead[parent_2] = 1;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
785 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
787 for (i = 0; i < len; i++) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
788 PyObject *head;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
789
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
790 if (nothead[i])
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
791 continue;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
792 head = PyInt_FromLong(i);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
793 if (head == NULL || PyList_Append(heads, head) == -1) {
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
794 Py_XDECREF(head);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
795 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
796 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
797 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
798
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
799 done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
800 self->headrevs = heads;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
801 free(nothead);
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
802 return list_copy(self->headrevs);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
803 bail:
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
804 Py_XDECREF(heads);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
805 free(nothead);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
806 return NULL;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
807 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
808
16618
6bae941b58ad parsers: change the type of nt_level
Bryan O'Sullivan <bryano@fb.com>
parents: 16617
diff changeset
809 static inline int nt_level(const char *node, Py_ssize_t level)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
810 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
811 int v = node[level>>1];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
812 if (!(level & 1))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
813 v >>= 4;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
814 return v & 0xf;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
815 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
816
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
817 /*
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
818 * Return values:
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
819 *
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
820 * -4: match is ambiguous (multiple candidates)
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
821 * -2: not found
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
822 * rest: valid rev
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
823 */
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
824 static int nt_find(indexObject *self, const char *node, Py_ssize_t nodelen,
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
825 int hex)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
826 {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
827 int (*getnybble)(const char *, Py_ssize_t) = hex ? hexdigit : nt_level;
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
828 int level, maxlevel, off;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
829
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
830 if (nodelen == 20 && node[0] == '\0' && memcmp(node, nullid, 20) == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
831 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
832
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
833 if (self->nt == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
834 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
835
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
836 if (hex)
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
837 maxlevel = nodelen > 40 ? 40 : (int)nodelen;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
838 else
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
839 maxlevel = nodelen > 20 ? 40 : ((int)nodelen * 2);
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
840
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
841 for (level = off = 0; level < maxlevel; level++) {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
842 int k = getnybble(node, level);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
843 nodetree *n = &self->nt[off];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
844 int v = n->children[k];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
845
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
846 if (v < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
847 const char *n;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
848 Py_ssize_t i;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
849
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
850 v = -v - 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
851 n = index_node(self, v);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
852 if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
853 return -2;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
854 for (i = level; i < maxlevel; i++)
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
855 if (getnybble(node, i) != nt_level(n, i))
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
856 return -2;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
857 return v;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
858 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
859 if (v == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
860 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
861 off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
862 }
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
863 /* multiple matches against an ambiguous prefix */
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
864 return -4;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
865 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
866
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
867 static int nt_new(indexObject *self)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
868 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
869 if (self->ntlength == self->ntcapacity) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
870 self->ntcapacity *= 2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
871 self->nt = realloc(self->nt,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
872 self->ntcapacity * sizeof(nodetree));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
873 if (self->nt == NULL) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
874 PyErr_SetString(PyExc_MemoryError, "out of memory");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
875 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
876 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
877 memset(&self->nt[self->ntlength], 0,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
878 sizeof(nodetree) * (self->ntcapacity - self->ntlength));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
879 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
880 return self->ntlength++;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
881 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
882
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
883 static int nt_insert(indexObject *self, const char *node, int rev)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
884 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
885 int level = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
886 int off = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
887
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
888 while (level < 40) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
889 int k = nt_level(node, level);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
890 nodetree *n;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
891 int v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
892
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
893 n = &self->nt[off];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
894 v = n->children[k];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
895
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
896 if (v == 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
897 n->children[k] = -rev - 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
898 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
899 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
900 if (v < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
901 const char *oldnode = index_node(self, -v - 1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
902 int noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
903
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
904 if (!oldnode || !memcmp(oldnode, node, 20)) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
905 n->children[k] = -rev - 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
906 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
907 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
908 noff = nt_new(self);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
909 if (noff == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
910 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
911 /* self->nt may have been changed by realloc */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
912 self->nt[off].children[k] = noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
913 off = noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
914 n = &self->nt[off];
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
915 n->children[nt_level(oldnode, ++level)] = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
916 if (level > self->ntdepth)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
917 self->ntdepth = level;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
918 self->ntsplits += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
919 } else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
920 level += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
921 off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
922 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
923 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
924
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
925 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
926 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
927
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
928 static int nt_init(indexObject *self)
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
929 {
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
930 if (self->nt == NULL) {
20110
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
931 if (self->raw_length > INT_MAX) {
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
932 PyErr_SetString(PyExc_ValueError, "overflow in nt_init");
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
933 return -1;
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
934 }
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
935 self->ntcapacity = self->raw_length < 4
20110
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
936 ? 4 : (int)self->raw_length / 2;
40b7c6e4b993 mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents: 19728
diff changeset
937
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
938 self->nt = calloc(self->ntcapacity, sizeof(nodetree));
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
939 if (self->nt == NULL) {
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
940 PyErr_NoMemory();
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
941 return -1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
942 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
943 self->ntlength = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
944 self->ntrev = (int)index_length(self) - 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
945 self->ntlookups = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
946 self->ntmisses = 0;
16664
5bc6edf71b39 parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents: 16663
diff changeset
947 if (nt_insert(self, nullid, INT_MAX) == -1)
5bc6edf71b39 parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents: 16663
diff changeset
948 return -1;
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
949 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
950 return 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
951 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
952
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
953 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
954 * Return values:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
955 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
956 * -3: error (exception set)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
957 * -2: not found (no exception set)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
958 * rest: valid rev
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
959 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
960 static int index_find_node(indexObject *self,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
961 const char *node, Py_ssize_t nodelen)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
962 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
963 int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
964
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
965 self->ntlookups++;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
966 rev = nt_find(self, node, nodelen, 0);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
967 if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
968 return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
969
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
970 if (nt_init(self) == -1)
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
971 return -3;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
972
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
973 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
974 * For the first handful of lookups, we scan the entire index,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
975 * and cache only the matching nodes. This optimizes for cases
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
976 * like "hg tip", where only a few nodes are accessed.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
977 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
978 * After that, we cache every node we visit, using a single
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
979 * scan amortized over multiple lookups. This gives the best
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
980 * bulk performance, e.g. for "hg log".
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
981 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
982 if (self->ntmisses++ < 4) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
983 for (rev = self->ntrev - 1; rev >= 0; rev--) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
984 const char *n = index_node(self, rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
985 if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
986 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
987 if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
988 if (nt_insert(self, n, rev) == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
989 return -3;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
990 break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
991 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
992 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
993 } else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
994 for (rev = self->ntrev - 1; rev >= 0; rev--) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
995 const char *n = index_node(self, rev);
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
996 if (n == NULL) {
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
997 self->ntrev = rev + 1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
998 return -2;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
999 }
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
1000 if (nt_insert(self, n, rev) == -1) {
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
1001 self->ntrev = rev + 1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1002 return -3;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
1003 }
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1004 if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1005 break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1006 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1007 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1008 self->ntrev = rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1009 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1010
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1011 if (rev >= 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1012 return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1013 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1014 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1015
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1016 static PyObject *raise_revlog_error(void)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1017 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1018 static PyObject *errclass;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1019 PyObject *mod = NULL, *errobj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1020
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1021 if (errclass == NULL) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1022 PyObject *dict;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1023
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1024 mod = PyImport_ImportModule("mercurial.error");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1025 if (mod == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1026 goto classfail;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1027
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1028 dict = PyModule_GetDict(mod);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1029 if (dict == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1030 goto classfail;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1031
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1032 errclass = PyDict_GetItemString(dict, "RevlogError");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1033 if (errclass == NULL) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1034 PyErr_SetString(PyExc_SystemError,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1035 "could not find RevlogError");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1036 goto classfail;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1037 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1038 Py_INCREF(errclass);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1039 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1040
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1041 errobj = PyObject_CallFunction(errclass, NULL);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1042 if (errobj == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1043 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1044 PyErr_SetObject(errclass, errobj);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1045 return errobj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1046
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1047 classfail:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1048 Py_XDECREF(mod);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1049 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1050 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1051
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1052 static PyObject *index_getitem(indexObject *self, PyObject *value)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1053 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1054 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1055 Py_ssize_t nodelen;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1056 int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1057
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1058 if (PyInt_Check(value))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1059 return index_get(self, PyInt_AS_LONG(value));
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1060
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1061 if (node_check(value, &node, &nodelen) == -1)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1062 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1063 rev = index_find_node(self, node, nodelen);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1064 if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1065 return PyInt_FromLong(rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1066 if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1067 raise_revlog_error();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1068 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1069 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1070
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1071 static int nt_partialmatch(indexObject *self, const char *node,
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1072 Py_ssize_t nodelen)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1073 {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1074 int rev;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1075
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1076 if (nt_init(self) == -1)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1077 return -3;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1078
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1079 if (self->ntrev > 0) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1080 /* ensure that the radix tree is fully populated */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1081 for (rev = self->ntrev - 1; rev >= 0; rev--) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1082 const char *n = index_node(self, rev);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1083 if (n == NULL)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1084 return -2;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1085 if (nt_insert(self, n, rev) == -1)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1086 return -3;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1087 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1088 self->ntrev = rev;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1089 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1090
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1091 return nt_find(self, node, nodelen, 1);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1092 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1093
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1094 static PyObject *index_partialmatch(indexObject *self, PyObject *args)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1095 {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1096 const char *fullnode;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1097 int nodelen;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1098 char *node;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1099 int rev, i;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1100
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1101 if (!PyArg_ParseTuple(args, "s#", &node, &nodelen))
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1102 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1103
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1104 if (nodelen < 4) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1105 PyErr_SetString(PyExc_ValueError, "key too short");
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1106 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1107 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1108
17353
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
1109 if (nodelen > 40) {
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
1110 PyErr_SetString(PyExc_ValueError, "key too long");
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
1111 return NULL;
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
1112 }
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1113
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1114 for (i = 0; i < nodelen; i++)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1115 hexdigit(node, i);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1116 if (PyErr_Occurred()) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1117 /* input contains non-hex characters */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1118 PyErr_Clear();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1119 Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1120 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1121
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1122 rev = nt_partialmatch(self, node, nodelen);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1123
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1124 switch (rev) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1125 case -4:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1126 raise_revlog_error();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1127 case -3:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1128 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1129 case -2:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1130 Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1131 case -1:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1132 return PyString_FromStringAndSize(nullid, 20);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1133 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1134
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1135 fullnode = index_node(self, rev);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1136 if (fullnode == NULL) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1137 PyErr_Format(PyExc_IndexError,
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1138 "could not access rev %d", rev);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1139 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1140 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1141 return PyString_FromStringAndSize(fullnode, 20);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1142 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1143
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1144 static PyObject *index_m_get(indexObject *self, PyObject *args)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1145 {
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1146 Py_ssize_t nodelen;
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1147 PyObject *val;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1148 char *node;
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1149 int rev;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1150
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1151 if (!PyArg_ParseTuple(args, "O", &val))
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1152 return NULL;
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1153 if (node_check(val, &node, &nodelen) == -1)
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1154 return NULL;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1155 rev = index_find_node(self, node, nodelen);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1156 if (rev == -3)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1157 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1158 if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1159 Py_RETURN_NONE;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1160 return PyInt_FromLong(rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1161 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1162
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1163 static int index_contains(indexObject *self, PyObject *value)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1164 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1165 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1166 Py_ssize_t nodelen;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1167
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1168 if (PyInt_Check(value)) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1169 long rev = PyInt_AS_LONG(value);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1170 return rev >= -1 && rev < index_length(self);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1171 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1172
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1173 if (node_check(value, &node, &nodelen) == -1)
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
1174 return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1175
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1176 switch (index_find_node(self, node, nodelen)) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1177 case -3:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1178 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1179 case -2:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1180 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1181 default:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1182 return 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1183 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1184 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1185
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1186 static inline void index_get_parents(indexObject *self, int rev, int *ps)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1187 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1188 if (rev >= self->length - 1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1189 PyObject *tuple = PyList_GET_ITEM(self->added,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1190 rev - self->length + 1);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1191 ps[0] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 5));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1192 ps[1] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 6));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1193 } else {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1194 const char *data = index_deref(self, rev);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1195 ps[0] = getbe32(data + 24);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1196 ps[1] = getbe32(data + 28);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1197 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1198 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1199
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1200 typedef uint64_t bitmask;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1201
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1202 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1203 * Given a disjoint set of revs, return all candidates for the
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1204 * greatest common ancestor. In revset notation, this is the set
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1205 * "heads(::a and ::b and ...)"
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1206 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1207 static PyObject *find_gca_candidates(indexObject *self, const int *revs,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1208 int revcount)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1209 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1210 const bitmask allseen = (1ull << revcount) - 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1211 const bitmask poison = 1ull << revcount;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1212 PyObject *gca = PyList_New(0);
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
1213 int i, v, interesting;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1214 int maxrev = -1;
19030
48d6f436363e parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents: 18988
diff changeset
1215 long sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1216 bitmask *seen;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1217
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
1218 if (gca == NULL)
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
1219 return PyErr_NoMemory();
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
1220
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1221 for (i = 0; i < revcount; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1222 if (revs[i] > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1223 maxrev = revs[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1224 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1225
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1226 seen = calloc(sizeof(*seen), maxrev + 1);
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
1227 if (seen == NULL) {
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
1228 Py_DECREF(gca);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1229 return PyErr_NoMemory();
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
1230 }
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1231
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1232 for (i = 0; i < revcount; i++)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1233 seen[revs[i]] = 1ull << i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1234
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
1235 interesting = revcount;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1236
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1237 for (v = maxrev; v >= 0 && interesting; v--) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1238 long sv = seen[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1239 int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1240
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1241 if (!sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1242 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1243
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1244 if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1245 interesting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1246 if (sv == allseen) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1247 PyObject *obj = PyInt_FromLong(v);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1248 if (obj == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1249 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1250 if (PyList_Append(gca, obj) == -1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1251 Py_DECREF(obj);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1252 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1253 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1254 sv |= poison;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1255 for (i = 0; i < revcount; i++) {
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
1256 if (revs[i] == v)
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
1257 goto done;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1258 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1259 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1260 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1261 index_get_parents(self, v, parents);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1262
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1263 for (i = 0; i < 2; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1264 int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1265 if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1266 continue;
19030
48d6f436363e parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents: 18988
diff changeset
1267 sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1268 if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1269 if (sp == 0) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1270 seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1271 interesting++;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1272 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1273 else if (sp != sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1274 seen[p] |= sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1275 } else {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1276 if (sp && sp < poison)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1277 interesting--;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1278 seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1279 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1280 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1281 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1282
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1283 done:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1284 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1285 return gca;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1286 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1287 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1288 Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1289 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1290 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1291
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1292 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1293 * Given a disjoint set of revs, return the subset with the longest
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1294 * path to the root.
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1295 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1296 static PyObject *find_deepest(indexObject *self, PyObject *revs)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1297 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1298 const Py_ssize_t revcount = PyList_GET_SIZE(revs);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1299 static const Py_ssize_t capacity = 24;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1300 int *depth, *interesting = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1301 int i, j, v, ninteresting;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1302 PyObject *dict = NULL, *keys;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1303 long *seen = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1304 int maxrev = -1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1305 long final;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1306
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1307 if (revcount > capacity) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1308 PyErr_Format(PyExc_OverflowError,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1309 "bitset size (%ld) > capacity (%ld)",
19062
365b0de17c1c parsers: remove warning: format ‘%ld’ expects argument of type ‘long int’
André Sintzoff <andre.sintzoff@gmail.com>
parents: 19030
diff changeset
1310 (long)revcount, (long)capacity);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1311 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1312 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1313
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1314 for (i = 0; i < revcount; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1315 int n = (int)PyInt_AsLong(PyList_GET_ITEM(revs, i));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1316 if (n > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1317 maxrev = n;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1318 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1319
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1320 depth = calloc(sizeof(*depth), maxrev + 1);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1321 if (depth == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1322 return PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1323
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1324 seen = calloc(sizeof(*seen), maxrev + 1);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1325 if (seen == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1326 PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1327 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1328 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1329
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1330 interesting = calloc(sizeof(*interesting), 2 << revcount);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1331 if (interesting == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1332 PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1333 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1334 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1335
19502
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
1336 if (PyList_Sort(revs) == -1)
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
1337 goto bail;
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
1338
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1339 for (i = 0; i < revcount; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1340 int n = (int)PyInt_AsLong(PyList_GET_ITEM(revs, i));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1341 long b = 1l << i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1342 depth[n] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1343 seen[n] = b;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1344 interesting[b] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1345 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1346
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1347 ninteresting = (int)revcount;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1348
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1349 for (v = maxrev; v >= 0 && ninteresting > 1; v--) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1350 int dv = depth[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1351 int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1352 long sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1353
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1354 if (dv == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1355 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1356
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1357 sv = seen[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1358 index_get_parents(self, v, parents);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1359
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1360 for (i = 0; i < 2; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1361 int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1362 long nsp, sp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1363 int dp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1364
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1365 if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1366 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1367
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1368 dp = depth[p];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1369 nsp = sp = seen[p];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1370 if (dp <= dv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1371 depth[p] = dv + 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1372 if (sp != sv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1373 interesting[sv] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1374 nsp = seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1375 if (sp) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1376 interesting[sp] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1377 if (interesting[sp] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1378 ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1379 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1380 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1381 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1382 else if (dv == dp - 1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1383 nsp = sp | sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1384 if (nsp == sp)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1385 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1386 seen[p] = nsp;
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
1387 interesting[sp] -= 1;
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
1388 if (interesting[sp] == 0 && interesting[nsp] > 0)
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
1389 ninteresting -= 1;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1390 interesting[nsp] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1391 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1392 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1393 interesting[sv] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1394 if (interesting[sv] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1395 ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1396 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1397
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1398 final = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1399 j = ninteresting;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1400 for (i = 0; i < (int)(2 << revcount) && j > 0; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1401 if (interesting[i] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1402 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1403 final |= i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1404 j -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1405 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1406 if (final == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1407 return PyList_New(0);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1408
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1409 dict = PyDict_New();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1410 if (dict == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1411 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1412
19504
2fa303619b4d ancestor.deepest: ignore ninteresting while building result (issue3984)
Siddharth Agarwal <sid0@fb.com>
parents: 19503
diff changeset
1413 for (i = 0; i < revcount; i++) {
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1414 PyObject *key;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1415
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1416 if ((final & (1 << i)) == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1417 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1418
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1419 key = PyList_GET_ITEM(revs, i);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1420 Py_INCREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1421 Py_INCREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1422 if (PyDict_SetItem(dict, key, Py_None) == -1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1423 Py_DECREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1424 Py_DECREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1425 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1426 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1427 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1428
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1429 keys = PyDict_Keys(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1430
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1431 free(depth);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1432 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1433 free(interesting);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1434 Py_DECREF(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1435
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1436 return keys;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1437 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1438 free(depth);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1439 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1440 free(interesting);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1441 Py_XDECREF(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1442
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1443 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1444 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1445
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1446 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1447 * Given a (possibly overlapping) set of revs, return the greatest
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1448 * common ancestors: those with the longest path to the root.
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1449 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1450 static PyObject *index_ancestors(indexObject *self, PyObject *args)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1451 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1452 PyObject *ret = NULL, *gca = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1453 Py_ssize_t argcount, i, len;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1454 bitmask repeat = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1455 int revcount = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1456 int *revs;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1457
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1458 argcount = PySequence_Length(args);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1459 revs = malloc(argcount * sizeof(*revs));
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1460 if (argcount > 0 && revs == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1461 return PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1462 len = index_length(self) - 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1463
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1464 for (i = 0; i < argcount; i++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1465 static const int capacity = 24;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1466 PyObject *obj = PySequence_GetItem(args, i);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1467 bitmask x;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1468 long val;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1469
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1470 if (!PyInt_Check(obj)) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1471 PyErr_SetString(PyExc_TypeError,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1472 "arguments must all be ints");
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1473 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1474 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1475 val = PyInt_AsLong(obj);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1476 if (val == -1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1477 ret = PyList_New(0);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1478 goto done;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1479 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1480 if (val < 0 || val >= len) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1481 PyErr_SetString(PyExc_IndexError,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1482 "index out of range");
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1483 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1484 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1485 /* this cheesy bloom filter lets us avoid some more
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1486 * expensive duplicate checks in the common set-is-disjoint
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1487 * case */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1488 x = 1ull << (val & 0x3f);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1489 if (repeat & x) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1490 int k;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1491 for (k = 0; k < revcount; k++) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1492 if (val == revs[k])
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1493 goto duplicate;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1494 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1495 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1496 else repeat |= x;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1497 if (revcount >= capacity) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1498 PyErr_Format(PyExc_OverflowError,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1499 "bitset size (%d) > capacity (%d)",
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1500 revcount, capacity);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1501 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1502 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1503 revs[revcount++] = (int)val;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1504 duplicate:;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1505 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1506
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1507 if (revcount == 0) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1508 ret = PyList_New(0);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1509 goto done;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1510 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1511 if (revcount == 1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1512 PyObject *obj;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1513 ret = PyList_New(1);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1514 if (ret == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1515 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1516 obj = PyInt_FromLong(revs[0]);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1517 if (obj == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1518 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1519 PyList_SET_ITEM(ret, 0, obj);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1520 goto done;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1521 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1522
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1523 gca = find_gca_candidates(self, revs, revcount);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1524 if (gca == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1525 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1526
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1527 if (PyList_GET_SIZE(gca) <= 1) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1528 ret = gca;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1529 Py_INCREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1530 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1531 else ret = find_deepest(self, gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1532
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1533 done:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1534 free(revs);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1535 Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1536
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1537 return ret;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1538
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1539 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1540 free(revs);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1541 Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1542 Py_XDECREF(ret);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1543 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1544 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1545
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1546 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1547 * Invalidate any trie entries introduced by added revs.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1548 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1549 static void nt_invalidate_added(indexObject *self, Py_ssize_t start)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1550 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1551 Py_ssize_t i, len = PyList_GET_SIZE(self->added);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1552
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1553 for (i = start; i < len; i++) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1554 PyObject *tuple = PyList_GET_ITEM(self->added, i);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1555 PyObject *node = PyTuple_GET_ITEM(tuple, 7);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1556
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1557 nt_insert(self, PyString_AS_STRING(node), -1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1558 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1559
16732
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
1560 if (start == 0)
277e2acb7e5c parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents: 16699
diff changeset
1561 Py_CLEAR(self->added);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1562 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1563
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1564 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1565 * Delete a numeric range of revs, which must be at the end of the
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1566 * range, but exclude the sentinel nullid entry.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1567 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1568 static int index_slice_del(indexObject *self, PyObject *item)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1569 {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1570 Py_ssize_t start, stop, step, slicelength;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1571 Py_ssize_t length = index_length(self);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1572 int ret = 0;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1573
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1574 if (PySlice_GetIndicesEx((PySliceObject*)item, length,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1575 &start, &stop, &step, &slicelength) < 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1576 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1577
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1578 if (slicelength <= 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1579 return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1580
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1581 if ((step < 0 && start < stop) || (step > 0 && start > stop))
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1582 stop = start;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1583
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1584 if (step < 0) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1585 stop = start + 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1586 start = stop + step*(slicelength - 1) - 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1587 step = -step;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1588 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1589
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1590 if (step != 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1591 PyErr_SetString(PyExc_ValueError,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1592 "revlog index delete requires step size of 1");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1593 return -1;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1594 }
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1595
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1596 if (stop != length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1597 PyErr_SetString(PyExc_IndexError,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1598 "revlog index deletion indices are invalid");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1599 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1600 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1601
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1602 if (start < self->length - 1) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1603 if (self->nt) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1604 Py_ssize_t i;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1605
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1606 for (i = start + 1; i < self->length - 1; i++) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1607 const char *node = index_node(self, i);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1608
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1609 if (node)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1610 nt_insert(self, node, -1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1611 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1612 if (self->added)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1613 nt_invalidate_added(self, 0);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1614 if (self->ntrev > start)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1615 self->ntrev = (int)start;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1616 }
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1617 self->length = start + 1;
18504
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1618 if (start < self->raw_length) {
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1619 if (self->cache) {
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1620 Py_ssize_t i;
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1621 for (i = start; i < self->raw_length; i++)
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1622 Py_CLEAR(self->cache[i]);
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1623 }
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1624 self->raw_length = start;
18504
d1d5fdcc2d46 parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents: 18430
diff changeset
1625 }
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1626 goto done;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1627 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1628
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1629 if (self->nt) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1630 nt_invalidate_added(self, start - self->length + 1);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1631 if (self->ntrev > start)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1632 self->ntrev = (int)start;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1633 }
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1634 if (self->added)
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1635 ret = PyList_SetSlice(self->added, start - self->length + 1,
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1636 PyList_GET_SIZE(self->added), NULL);
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1637 done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
1638 Py_CLEAR(self->headrevs);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
1639 return ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1640 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1641
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1642 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1643 * Supported ops:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1644 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1645 * slice deletion
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1646 * string assignment (extend node->rev mapping)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1647 * string deletion (shrink node->rev mapping)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1648 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1649 static int index_assign_subscript(indexObject *self, PyObject *item,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1650 PyObject *value)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1651 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1652 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1653 Py_ssize_t nodelen;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1654 long rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1655
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1656 if (PySlice_Check(item) && value == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1657 return index_slice_del(self, item);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1658
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1659 if (node_check(item, &node, &nodelen) == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1660 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1661
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1662 if (value == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1663 return self->nt ? nt_insert(self, node, -1) : 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1664 rev = PyInt_AsLong(value);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1665 if (rev > INT_MAX || rev < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1666 if (!PyErr_Occurred())
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1667 PyErr_SetString(PyExc_ValueError, "rev out of range");
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1668 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1669 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1670 return nt_insert(self, node, (int)rev);
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1671 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1672
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1673 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1674 * Find all RevlogNG entries in an index that has inline data. Update
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1675 * the optional "offsets" table with those entries.
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1676 */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1677 static long inline_scan(indexObject *self, const char **offsets)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1678 {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1679 const char *data = PyString_AS_STRING(self->data);
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1680 Py_ssize_t pos = 0;
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1681 Py_ssize_t end = PyString_GET_SIZE(self->data);
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
1682 long incr = v1_hdrsize;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1683 Py_ssize_t len = 0;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
1684
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1685 while (pos + v1_hdrsize <= end && pos >= 0) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1686 uint32_t comp_len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1687 /* 3rd element of header is length of compressed inline data */
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1688 comp_len = getbe32(data + pos + 8);
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
1689 incr = v1_hdrsize + comp_len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1690 if (offsets)
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1691 offsets[len] = data + pos;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1692 len++;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1693 pos += incr;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1694 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
1695
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
1696 if (pos != end) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1697 if (!PyErr_Occurred())
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1698 PyErr_SetString(PyExc_ValueError, "corrupt index file");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1699 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1700 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1701
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1702 return len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1703 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
1704
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1705 static int index_init(indexObject *self, PyObject *args)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1706 {
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1707 PyObject *data_obj, *inlined_obj;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1708 Py_ssize_t size;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1709
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1710 /* Initialize before argument-checking to avoid index_dealloc() crash. */
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1711 self->raw_length = 0;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1712 self->added = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1713 self->cache = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1714 self->data = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1715 self->headrevs = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1716 self->nt = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1717 self->offsets = NULL;
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1718
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1719 if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj))
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1720 return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1721 if (!PyString_Check(data_obj)) {
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1722 PyErr_SetString(PyExc_TypeError, "data is not a string");
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1723 return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1724 }
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1725 size = PyString_GET_SIZE(data_obj);
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1726
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1727 self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1728 self->data = data_obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1729
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1730 self->ntlength = self->ntcapacity = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1731 self->ntdepth = self->ntsplits = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1732 self->ntlookups = self->ntmisses = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1733 self->ntrev = -1;
16597
b767382a8675 parsers: fix refcount bug on corrupt index
Matt Mackall <mpm@selenic.com>
parents: 16572
diff changeset
1734 Py_INCREF(self->data);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1735
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1736 if (self->inlined) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1737 long len = inline_scan(self, NULL);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1738 if (len == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1739 goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1740 self->raw_length = len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1741 self->length = len + 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1742 } else {
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
1743 if (size % v1_hdrsize) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1744 PyErr_SetString(PyExc_ValueError, "corrupt index file");
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1745 goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1746 }
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
1747 self->raw_length = size / v1_hdrsize;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1748 self->length = self->raw_length + 1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1749 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1750
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1751 return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1752 bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1753 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1754 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1755
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1756 static PyObject *index_nodemap(indexObject *self)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1757 {
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1758 Py_INCREF(self);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1759 return (PyObject *)self;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1760 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1761
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1762 static void index_dealloc(indexObject *self)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1763 {
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
1764 _index_clearcaches(self);
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
1765 Py_XDECREF(self->data);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1766 Py_XDECREF(self->added);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1767 PyObject_Del(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1768 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1769
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1770 static PySequenceMethods index_sequence_methods = {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1771 (lenfunc)index_length, /* sq_length */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1772 0, /* sq_concat */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1773 0, /* sq_repeat */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1774 (ssizeargfunc)index_get, /* sq_item */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1775 0, /* sq_slice */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1776 0, /* sq_ass_item */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1777 0, /* sq_ass_slice */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1778 (objobjproc)index_contains, /* sq_contains */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1779 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1780
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1781 static PyMappingMethods index_mapping_methods = {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1782 (lenfunc)index_length, /* mp_length */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1783 (binaryfunc)index_getitem, /* mp_subscript */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1784 (objobjargproc)index_assign_subscript, /* mp_ass_subscript */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1785 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1786
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1787 static PyMethodDef index_methods[] = {
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1788 {"ancestors", (PyCFunction)index_ancestors, METH_VARARGS,
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
1789 "return the gca set of the given revs"},
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
1790 {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
1791 "clear the index caches"},
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1792 {"get", (PyCFunction)index_m_get, METH_VARARGS,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1793 "get an index entry"},
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1794 {"headrevs", (PyCFunction)index_headrevs, METH_NOARGS,
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1795 "get head revisions"},
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1796 {"insert", (PyCFunction)index_insert, METH_VARARGS,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1797 "insert an index entry"},
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1798 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
1799 "match a potentially ambiguous node ID"},
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1800 {"stats", (PyCFunction)index_stats, METH_NOARGS,
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1801 "stats for the index"},
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1802 {NULL} /* Sentinel */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1803 };
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1804
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1805 static PyGetSetDef index_getset[] = {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1806 {"nodemap", (getter)index_nodemap, NULL, "nodemap", NULL},
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1807 {NULL} /* Sentinel */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1808 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1809
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1810 static PyTypeObject indexType = {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1811 PyObject_HEAD_INIT(NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1812 0, /* ob_size */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1813 "parsers.index", /* tp_name */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1814 sizeof(indexObject), /* tp_basicsize */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1815 0, /* tp_itemsize */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1816 (destructor)index_dealloc, /* tp_dealloc */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1817 0, /* tp_print */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1818 0, /* tp_getattr */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1819 0, /* tp_setattr */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1820 0, /* tp_compare */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1821 0, /* tp_repr */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1822 0, /* tp_as_number */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1823 &index_sequence_methods, /* tp_as_sequence */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1824 &index_mapping_methods, /* tp_as_mapping */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1825 0, /* tp_hash */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1826 0, /* tp_call */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1827 0, /* tp_str */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1828 0, /* tp_getattro */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1829 0, /* tp_setattro */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1830 0, /* tp_as_buffer */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1831 Py_TPFLAGS_DEFAULT, /* tp_flags */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1832 "revlog index", /* tp_doc */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1833 0, /* tp_traverse */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1834 0, /* tp_clear */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1835 0, /* tp_richcompare */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1836 0, /* tp_weaklistoffset */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1837 0, /* tp_iter */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1838 0, /* tp_iternext */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1839 index_methods, /* tp_methods */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1840 0, /* tp_members */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1841 index_getset, /* tp_getset */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1842 0, /* tp_base */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1843 0, /* tp_dict */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1844 0, /* tp_descr_get */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1845 0, /* tp_descr_set */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1846 0, /* tp_dictoffset */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1847 (initproc)index_init, /* tp_init */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1848 0, /* tp_alloc */
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1849 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1850
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1851 /*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1852 * returns a tuple of the form (index, index, cache) with elements as
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1853 * follows:
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1854 *
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1855 * index: an index object that lazily parses RevlogNG records
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1856 * cache: if data is inlined, a tuple (index_file_content, 0), else None
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1857 *
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1858 * added complications are for backwards compatibility
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1859 */
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
1860 static PyObject *parse_index2(PyObject *self, PyObject *args)
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1861 {
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1862 PyObject *tuple = NULL, *cache = NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1863 indexObject *idx;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1864 int ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1865
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1866 idx = PyObject_New(indexObject, &indexType);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1867 if (idx == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1868 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1869
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1870 ret = index_init(idx, args);
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
1871 if (ret == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1872 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1873
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1874 if (idx->inlined) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1875 cache = Py_BuildValue("iO", 0, idx->data);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1876 if (cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1877 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1878 } else {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1879 cache = Py_None;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1880 Py_INCREF(cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1881 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1882
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1883 tuple = Py_BuildValue("NN", idx, cache);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1884 if (!tuple)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1885 goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1886 return tuple;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1887
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1888 bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1889 Py_XDECREF(idx);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1890 Py_XDECREF(cache);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1891 Py_XDECREF(tuple);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1892 return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1893 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
1894
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1895 static char parsers_doc[] = "Efficient content parsing.";
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1896
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17356
diff changeset
1897 PyObject *encodedir(PyObject *self, PyObject *args);
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
1898 PyObject *pathencode(PyObject *self, PyObject *args);
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17616
diff changeset
1899 PyObject *lowerencode(PyObject *self, PyObject *args);
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17356
diff changeset
1900
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1901 static PyMethodDef methods[] = {
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
1902 {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"},
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1903 {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"},
7093
16bafcebd3d1 dirstate: C parsing extension
Matt Mackall <mpm@selenic.com>
parents: 7092
diff changeset
1904 {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"},
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
1905 {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"},
17606
318fb32b980e pathencode: new C module with fast encodedir() function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17356
diff changeset
1906 {"encodedir", encodedir, METH_VARARGS, "encodedir a path\n"},
17616
9535a0dc41f2 store: implement fncache basic path encoding in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17606
diff changeset
1907 {"pathencode", pathencode, METH_VARARGS, "fncache-encode a path\n"},
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 17616
diff changeset
1908 {"lowerencode", lowerencode, METH_VARARGS, "lower-encode a path\n"},
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1909 {NULL, NULL}
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1910 };
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1911
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
1912 void dirs_module_init(PyObject *mod);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
1913
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1914 static void module_init(PyObject *mod)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1915 {
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1916 /* This module constant has two purposes. First, it lets us unit test
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1917 * the ImportError raised without hard-coding any error text. This
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1918 * means we can change the text in the future without breaking tests,
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1919 * even across changesets without a recompile. Second, its presence
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1920 * can be used to determine whether the version-checking logic is
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1921 * present, which also helps in testing across changesets without a
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1922 * recompile. Note that this means the pure-Python version of parsers
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1923 * should not have this module constant. */
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1924 PyModule_AddStringConstant(mod, "versionerrortext", versionerrortext);
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1925
18900
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
1926 dirs_module_init(mod);
02ee846b246a scmutil: rewrite dirs in C, use if available
Bryan O'Sullivan <bryano@fb.com>
parents: 18567
diff changeset
1927
16604
48e42f984074 parsers: statically initializing tp_new to PyType_GenericNew is not portable
Adrian Buehlmann <adrian@cadifra.com>
parents: 16597
diff changeset
1928 indexType.tp_new = PyType_GenericNew;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1929 if (PyType_Ready(&indexType) < 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1930 return;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1931 Py_INCREF(&indexType);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1932
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1933 PyModule_AddObject(mod, "index", (PyObject *)&indexType);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1934
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1935 nullentry = Py_BuildValue("iiiiiiis#", 0, 0, 0,
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1936 -1, -1, -1, -1, nullid, 20);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1937 if (nullentry)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1938 PyObject_GC_UnTrack(nullentry);
16955
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
1939
92e1c64ba0d4 parsers: add a C function to pack the dirstate
Bryan O'Sullivan <bryano@fb.com>
parents: 16863
diff changeset
1940 dirstate_unset = Py_BuildValue("ciii", 'n', 0, -1, -1);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1941 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1942
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1943 static int check_python_version(void)
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1944 {
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1945 PyObject *sys = PyImport_ImportModule("sys");
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1946 long hexversion = PyInt_AsLong(PyObject_GetAttrString(sys, "hexversion"));
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1947 /* sys.hexversion is a 32-bit number by default, so the -1 case
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1948 * should only occur in unusual circumstances (e.g. if sys.hexversion
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1949 * is manually set to an invalid value). */
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1950 if ((hexversion == -1) || (hexversion >> 16 != PY_VERSION_HEX >> 16)) {
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1951 PyErr_Format(PyExc_ImportError, "%s: The Mercurial extension "
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1952 "modules were compiled with Python " PY_VERSION ", but "
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1953 "Mercurial is currently using Python with sys.hexversion=%ld: "
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1954 "Python %s\n at: %s", versionerrortext, hexversion,
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1955 Py_GetVersion(), Py_GetProgramFullPath());
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1956 return -1;
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1957 }
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1958 return 0;
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1959 }
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1960
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1961 #ifdef IS_PY3K
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1962 static struct PyModuleDef parsers_module = {
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1963 PyModuleDef_HEAD_INIT,
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1964 "parsers",
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1965 parsers_doc,
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1966 -1,
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1967 methods
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1968 };
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1969
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1970 PyMODINIT_FUNC PyInit_parsers(void)
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1971 {
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1972 if (check_python_version() == -1)
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1973 return;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1974 PyObject *mod = PyModule_Create(&parsers_module);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1975 module_init(mod);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1976 return mod;
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1977 }
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1978 #else
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1979 PyMODINIT_FUNC initparsers(void)
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1980 {
20742
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1981 if (check_python_version() == -1)
3681de20b0a7 parsers: fail fast if Python has wrong minor version (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 20555
diff changeset
1982 return;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1983 PyObject *mod = Py_InitModule3("parsers", methods, parsers_doc);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
1984 module_init(mod);
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1985 }
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
1986 #endif