Mercurial > hg
annotate mercurial/cext/revlog.c @ 35816:f6ca1e11d8b4 stable
revset: evaluate filesets against each revision for 'file()' (issue5778)
After f2aeff8a87b6, the fileset was evaluated to a set of files against the
working directory, and then those files were applied against each revision. The
result was nonsense. For example, `hg log -r 'file("set:exec()")'` on the
Mercurial repo listed revision 0 because it has the `hg` script, which is
currently +x. But that bit wasn't applied until revision 280 (which
'contains()' properly indicates).
This technique was borrowed from checkstatus(), which services adds(),
modifies(), and removes(), so it seems safe enough. The 'r:' case is explicitly
assigned to wdirrev, freeing up rev=None to mean "re-evaluate at each revision".
The distinction is important to avoid behavior changes with `hg log set:...`
(test-largefiles-misc.t and test-fileset-generated.t drop current log output
without this). I'm not sure what the right behavior for that is (1fd352aa08fc
explicitly enabled this behavior for graphlog), but the day before the release
isn't the time to experiment.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sun, 28 Jan 2018 14:08:59 -0500 |
parents | d13526333835 |
children | 1f8c3fadbb8e |
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> |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
11 #include <assert.h> |
6389
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
12 #include <ctype.h> |
17356
511dfb34b412
parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents:
17353
diff
changeset
|
13 #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
|
14 #include <string.h> |
0231f763ebc8
manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff
changeset
|
15 |
34438
b90e8da190da
cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34437
diff
changeset
|
16 #include "bitmanipulation.h" |
33758
0f4ac3b6dee4
cext: factor out header for charencode.c
Yuya Nishihara <yuya@tcha.org>
parents:
33475
diff
changeset
|
17 #include "charencode.h" |
11361
3de3d670d2b6
parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents:
10449
diff
changeset
|
18 #include "util.h" |
3de3d670d2b6
parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents:
10449
diff
changeset
|
19 |
30112
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
20 #ifdef IS_PY3K |
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
21 /* The mapping of Python types is meant to be temporary to get Python |
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
22 * 3 to compile. We should remove this once Python 3 support is fully |
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
23 * supported and proper types are used in the extensions themselves. */ |
30169
5f7151e6de85
parsers: alias more PyInt* symbols on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30112
diff
changeset
|
24 #define PyInt_Check PyLong_Check |
30112
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
25 #define PyInt_FromLong PyLong_FromLong |
30169
5f7151e6de85
parsers: alias more PyInt* symbols on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30112
diff
changeset
|
26 #define PyInt_FromSsize_t PyLong_FromSsize_t |
5f7151e6de85
parsers: alias more PyInt* symbols on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30112
diff
changeset
|
27 #define PyInt_AS_LONG PyLong_AS_LONG |
30112
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
28 #define PyInt_AsLong PyLong_AsLong |
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
29 #endif |
9b6ff0f940ed
parsers: move PyInt aliasing out of util.h
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30103
diff
changeset
|
30 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
31 /* |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
32 * 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
|
33 * |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
34 * 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
|
35 * 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
|
36 * Zero is empty |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
37 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
38 typedef struct { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
39 int children[16]; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
40 } nodetree; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
41 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
42 /* |
26098 | 43 * This class has two behaviors. |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
44 * |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
45 * 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
|
46 * 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
|
47 * 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
|
48 * 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
|
49 * sentinel. |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
50 * |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
51 * 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
|
52 * 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
|
53 */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
54 typedef struct { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
55 PyObject_HEAD |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
56 /* Type-specific fields go here. */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
57 PyObject *data; /* raw bytes of index */ |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
58 Py_buffer buf; /* buffer of data */ |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
59 PyObject **cache; /* cached tuples */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
60 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
|
61 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
|
62 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
|
63 PyObject *added; /* populated on demand */ |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
64 PyObject *headrevs; /* cache, invalidated on changes */ |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
65 PyObject *filteredrevs;/* filtered revs set */ |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
66 nodetree *nt; /* base-16 trie */ |
26075
e7e7182564f6
parsers: avoid int/unsigned conversions
Augie Fackler <augie@google.com>
parents:
26059
diff
changeset
|
67 unsigned ntlength; /* # nodes in use */ |
e7e7182564f6
parsers: avoid int/unsigned conversions
Augie Fackler <augie@google.com>
parents:
26059
diff
changeset
|
68 unsigned ntcapacity; /* # nodes allocated */ |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
69 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
|
70 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
|
71 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
|
72 int ntlookups; /* # lookups */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
73 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
|
74 int inlined; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
75 } indexObject; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
76 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
77 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
|
78 { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
79 if (self->added == NULL) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
80 return self->length; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
81 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
|
82 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
83 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
84 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
|
85 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
|
86 |
22401
9ba8a93e55f5
parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents:
22400
diff
changeset
|
87 static Py_ssize_t inline_scan(indexObject *self, const char **offsets); |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
88 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
89 #if LONG_MAX == 0x7fffffffL |
16393
ee163a9cf37c
util.h: more Python 2.4 fixes
Matt Mackall <mpm@selenic.com>
parents:
16385
diff
changeset
|
90 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
|
91 #else |
16393
ee163a9cf37c
util.h: more Python 2.4 fixes
Matt Mackall <mpm@selenic.com>
parents:
16385
diff
changeset
|
92 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
|
93 #endif |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
94 |
16863
bbedef66c6f3
parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents:
16787
diff
changeset
|
95 /* 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
|
96 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
|
97 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
98 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
99 * 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
|
100 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
101 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
|
102 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
103 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
|
104 if (self->offsets == NULL) { |
31470
bc445c556d3c
parsers: use Python memory allocator for indexObject->offsets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31469
diff
changeset
|
105 self->offsets = PyMem_Malloc(self->raw_length * |
bc445c556d3c
parsers: use Python memory allocator for indexObject->offsets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31469
diff
changeset
|
106 sizeof(*self->offsets)); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
107 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
|
108 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
|
109 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
|
110 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
111 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
|
112 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
113 |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
114 return (const char *)(self->buf.buf) + 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
|
115 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
116 |
25810
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
117 static inline int index_get_parents(indexObject *self, Py_ssize_t rev, |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
118 int *ps, int maxrev) |
25311
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
119 { |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
120 if (rev >= self->length - 1) { |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
121 PyObject *tuple = PyList_GET_ITEM(self->added, |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
122 rev - self->length + 1); |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
123 ps[0] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 5)); |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
124 ps[1] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 6)); |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
125 } else { |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
126 const char *data = index_deref(self, rev); |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
127 ps[0] = getbe32(data + 24); |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
128 ps[1] = getbe32(data + 28); |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
129 } |
25810
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
130 /* If index file is corrupted, ps[] may point to invalid revisions. So |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
131 * there is a risk of buffer overflow to trust them unconditionally. */ |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
132 if (ps[0] > maxrev || ps[1] > maxrev) { |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
133 PyErr_SetString(PyExc_ValueError, "parent out of range"); |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
134 return -1; |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
135 } |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
136 return 0; |
25311
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
137 } |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
138 |
d2e88f960d1a
parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents:
25297
diff
changeset
|
139 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
140 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
141 * 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
|
142 * 6 bytes: offset |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
143 * 2 bytes: flags |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
144 * 4 bytes: compressed length |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
145 * 4 bytes: uncompressed length |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
146 * 4 bytes: base revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
147 * 4 bytes: link revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
148 * 4 bytes: parent 1 revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
149 * 4 bytes: parent 2 revision |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
150 * 32 bytes: nodeid (only 20 bytes used) |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
151 */ |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
152 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
|
153 { |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
154 uint64_t offset_flags; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
155 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
|
156 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
|
157 const char *data; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
158 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
|
159 PyObject *entry; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
160 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
161 if (pos < 0) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
162 pos += length; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
163 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
164 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
|
165 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
|
166 return NULL; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
167 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
168 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
169 if (pos == length - 1) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
170 Py_INCREF(nullentry); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
171 return nullentry; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
172 } |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
173 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
174 if (pos >= self->length - 1) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
175 PyObject *obj; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
176 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
|
177 Py_INCREF(obj); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
178 return obj; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
179 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
180 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
181 if (self->cache) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
182 if (self->cache[pos]) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
183 Py_INCREF(self->cache[pos]); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
184 return self->cache[pos]; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
185 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
186 } else { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
187 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
|
188 if (self->cache == NULL) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
189 return PyErr_NoMemory(); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
190 } |
7190
aecea6934fdd
Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
7186
diff
changeset
|
191 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
192 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
|
193 if (data == NULL) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
194 return NULL; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
195 |
16437
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
196 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
|
197 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
|
198 offset_flags &= 0xFFFF; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
199 else { |
16437
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
200 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
|
201 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
|
202 } |
7154
7fdf7a0a41b7
index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
7135
diff
changeset
|
203 |
16437
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
204 comp_len = getbe32(data + 8); |
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
205 uncomp_len = getbe32(data + 12); |
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
206 base_rev = getbe32(data + 16); |
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
207 link_rev = getbe32(data + 20); |
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
208 parent_1 = getbe32(data + 24); |
d126a0d16856
util.h: replace ntohl/htonl with get/putbe32
Matt Mackall <mpm@selenic.com>
parents:
16414
diff
changeset
|
209 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
|
210 c_node_id = data + 32; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
211 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
212 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
|
213 uncomp_len, base_rev, link_rev, |
5ef5eb1f3515
revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents:
11361
diff
changeset
|
214 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
|
215 |
19726
b3c8c6f2b5c1
parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents:
19725
diff
changeset
|
216 if (entry) { |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
217 PyObject_GC_UnTrack(entry); |
19726
b3c8c6f2b5c1
parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents:
19725
diff
changeset
|
218 Py_INCREF(entry); |
b3c8c6f2b5c1
parsers: use Py_INCREF safely
Bryan O'Sullivan <bryano@fb.com>
parents:
19725
diff
changeset
|
219 } |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
220 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
221 self->cache[pos] = entry; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
222 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
223 return entry; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
224 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
225 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
226 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
227 * 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
|
228 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
229 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
|
230 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
231 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
|
232 const char *data; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
233 |
16664
5bc6edf71b39
parsers: ensure that nullid is always present in the radix tree
Bryan O'Sullivan <bryano@fb.com>
parents:
16663
diff
changeset
|
234 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
|
235 return nullid; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
236 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
237 if (pos >= length) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
238 return NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
239 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
240 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
|
241 PyObject *tuple, *str; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
242 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
|
243 str = PyTuple_GetItem(tuple, 7); |
30100
c5afe5531709
parsers: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30090
diff
changeset
|
244 return str ? PyBytes_AS_STRING(str) : NULL; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
245 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
246 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
247 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
|
248 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
|
249 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
250 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
251 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
|
252 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
253 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
|
254 { |
30100
c5afe5531709
parsers: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30090
diff
changeset
|
255 if (PyBytes_AsStringAndSize(obj, 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
|
256 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
257 if (*nodelen == 20) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
258 return 0; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
259 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
|
260 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
261 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
262 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
263 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
|
264 { |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
265 PyObject *obj; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
266 char *node; |
22604
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
267 int index; |
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
268 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
|
269 |
22604
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
270 if (!PyArg_ParseTuple(args, "iO", &index, &obj)) |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
271 return NULL; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
272 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
273 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
|
274 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
|
275 return NULL; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
276 } |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
277 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
278 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
|
279 return NULL; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
280 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
281 len = index_length(self); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
282 |
22604
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
283 if (index < 0) |
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
284 index += len; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
285 |
22604
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
286 if (index != len - 1) { |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
287 PyErr_SetString(PyExc_IndexError, |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
288 "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
|
289 return NULL; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
290 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
291 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
292 if (self->added == NULL) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
293 self->added = PyList_New(0); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
294 if (self->added == NULL) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
295 return NULL; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
296 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
297 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
298 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
|
299 return NULL; |
13254
5ef5eb1f3515
revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents:
11361
diff
changeset
|
300 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
301 if (self->nt) |
22604
5e0d1478db8e
parsers: fix Py2.4 argument parsing issue
Matt Mackall <mpm@selenic.com>
parents:
22540
diff
changeset
|
302 nt_insert(self, node, index); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
303 |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
304 Py_CLEAR(self->headrevs); |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
305 Py_RETURN_NONE; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
306 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
307 |
16370
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
308 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
|
309 { |
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
310 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
|
311 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
|
312 |
16732
277e2acb7e5c
parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents:
16699
diff
changeset
|
313 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
|
314 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
|
315 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
|
316 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
|
317 } |
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
318 if (self->offsets) { |
31470
bc445c556d3c
parsers: use Python memory allocator for indexObject->offsets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31469
diff
changeset
|
319 PyMem_Free(self->offsets); |
16370
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
320 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
|
321 } |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
322 if (self->nt) { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
323 free(self->nt); |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
324 self->nt = NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
325 } |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
326 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
|
327 } |
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
328 |
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
329 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
|
330 { |
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
331 _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
|
332 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
|
333 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
|
334 self->ntrev = -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
335 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
|
336 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
|
337 } |
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
338 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
339 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
|
340 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
341 PyObject *obj = PyDict_New(); |
23948
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
342 PyObject *t = NULL; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
343 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
344 if (obj == NULL) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
345 return NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
346 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
347 #define istat(__n, __d) \ |
28792
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
348 do { \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
349 t = PyInt_FromSsize_t(self->__n); \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
350 if (!t) \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
351 goto bail; \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
352 if (PyDict_SetItemString(obj, __d, t) == -1) \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
353 goto bail; \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
354 Py_DECREF(t); \ |
507136150d2b
parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents:
28386
diff
changeset
|
355 } while (0) |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
356 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
357 if (self->added) { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
358 Py_ssize_t len = PyList_GET_SIZE(self->added); |
23948
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
359 t = PyInt_FromSsize_t(len); |
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
360 if (!t) |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
361 goto bail; |
23948
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
362 if (PyDict_SetItemString(obj, "index entries added", t) == -1) |
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
363 goto bail; |
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
364 Py_DECREF(t); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
365 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
366 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
367 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
|
368 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
|
369 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
|
370 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
|
371 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
|
372 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
|
373 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
|
374 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
|
375 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
|
376 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
|
377 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
378 #undef istat |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
379 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
380 return obj; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
381 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
382 bail: |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
383 Py_XDECREF(obj); |
23948
bd307b462ce2
parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents:
23947
diff
changeset
|
384 Py_XDECREF(t); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
385 return NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
386 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
387 |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
388 /* |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
389 * 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
|
390 * the cached copy. |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
391 */ |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
392 static PyObject *list_copy(PyObject *list) |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
393 { |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
394 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
|
395 PyObject *newlist = PyList_New(len); |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
396 Py_ssize_t i; |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
397 |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
398 if (newlist == NULL) |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
399 return NULL; |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
400 |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
401 for (i = 0; i < len; i++) { |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
402 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
|
403 Py_INCREF(obj); |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
404 PyList_SET_ITEM(newlist, i, obj); |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
405 } |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
406 |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
407 return newlist; |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
408 } |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
409 |
34440
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
410 static int check_filter(PyObject *filter, Py_ssize_t arg) |
7ed0750c71a1
cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents:
34438
diff
changeset
|
411 { |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
412 if (filter) { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
413 PyObject *arglist, *result; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
414 int isfiltered; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
415 |
26107
50582df9d7a7
parsers: fix two cases of unsigned long instead of Py_ssize_t
Augie Fackler <augie@google.com>
parents:
26098
diff
changeset
|
416 arglist = Py_BuildValue("(n)", arg); |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
417 if (!arglist) { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
418 return -1; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
419 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
420 |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
421 result = PyEval_CallObject(filter, arglist); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
422 Py_DECREF(arglist); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
423 if (!result) { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
424 return -1; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
425 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
426 |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
427 /* PyObject_IsTrue returns 1 if true, 0 if false, -1 if error, |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
428 * same as this function, so we can just return it directly.*/ |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
429 isfiltered = PyObject_IsTrue(result); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
430 Py_DECREF(result); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
431 return isfiltered; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
432 } else { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
433 return 0; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
434 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
435 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
436 |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
437 static Py_ssize_t add_roots_get_min(indexObject *self, PyObject *list, |
24499
90db70de6f9c
parsers.c: avoid implicit conversion loses integer warnings
André Sintzoff <andre.sintzoff@gmail.com>
parents:
24443
diff
changeset
|
438 Py_ssize_t marker, char *phases) |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
439 { |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
440 PyObject *iter = NULL; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
441 PyObject *iter_item = NULL; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
442 Py_ssize_t min_idx = index_length(self) + 1; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
443 long iter_item_long; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
444 |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
445 if (PyList_GET_SIZE(list) != 0) { |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
446 iter = PyObject_GetIter(list); |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
447 if (iter == NULL) |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
448 return -2; |
34437
ce26a13869fb
cext: move braces for control statements to same line
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33758
diff
changeset
|
449 while ((iter_item = PyIter_Next(iter))) { |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
450 iter_item_long = PyInt_AS_LONG(iter_item); |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
451 Py_DECREF(iter_item); |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
452 if (iter_item_long < min_idx) |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
453 min_idx = iter_item_long; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
454 phases[iter_item_long] = marker; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
455 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
456 Py_DECREF(iter); |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
457 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
458 |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
459 return min_idx; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
460 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
461 |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
462 static inline void set_phase_from_parents(char *phases, int parent_1, |
24499
90db70de6f9c
parsers.c: avoid implicit conversion loses integer warnings
André Sintzoff <andre.sintzoff@gmail.com>
parents:
24443
diff
changeset
|
463 int parent_2, Py_ssize_t i) |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
464 { |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
465 if (parent_1 >= 0 && phases[parent_1] > phases[i]) |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
466 phases[i] = phases[parent_1]; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
467 if (parent_2 >= 0 && phases[parent_2] > phases[i]) |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
468 phases[i] = phases[parent_2]; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
469 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
470 |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
471 static PyObject *reachableroots2(indexObject *self, PyObject *args) |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
472 { |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
473 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
474 /* Input */ |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
475 long minroot; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
476 PyObject *includepatharg = NULL; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
477 int includepath = 0; |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
478 /* heads and roots are lists */ |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
479 PyObject *heads = NULL; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
480 PyObject *roots = NULL; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
481 PyObject *reachable = NULL; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
482 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
483 PyObject *val; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
484 Py_ssize_t len = index_length(self) - 1; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
485 long revnum; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
486 Py_ssize_t k; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
487 Py_ssize_t i; |
26042
2a3010ba6f52
reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents:
26041
diff
changeset
|
488 Py_ssize_t l; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
489 int r; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
490 int parents[2]; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
491 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
492 /* Internal data structure: |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
493 * tovisit: array of length len+1 (all revs + nullrev), filled upto lentovisit |
26044
b3ad349d0e50
reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents:
26043
diff
changeset
|
494 * revstates: array of length len+1 (all revs + nullrev) */ |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
495 int *tovisit = NULL; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
496 long lentovisit = 0; |
26054
5049e10fed14
reachableroots: use internal "revstates" array to test if rev is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26053
diff
changeset
|
497 enum { RS_SEEN = 1, RS_ROOT = 2, RS_REACHABLE = 4 }; |
26043
f2f0a3ab6e41
reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents:
26042
diff
changeset
|
498 char *revstates = NULL; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
499 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
500 /* Get arguments */ |
26009
bbb698697efc
reachableroots: fix transposition of set and list types in PyArg_ParseTuple
Augie Fackler <augie@google.com>
parents:
26008
diff
changeset
|
501 if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads, |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
502 &PyList_Type, &roots, |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
503 &PyBool_Type, &includepatharg)) |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
504 goto bail; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
505 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
506 if (includepatharg == Py_True) |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
507 includepath = 1; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
508 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
509 /* Initialize return set */ |
26055
607868eccaa7
reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents:
26054
diff
changeset
|
510 reachable = PyList_New(0); |
607868eccaa7
reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents:
26054
diff
changeset
|
511 if (reachable == NULL) |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
512 goto bail; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
513 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
514 /* Initialize internal datastructures */ |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
515 tovisit = (int *)malloc((len + 1) * sizeof(int)); |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
516 if (tovisit == NULL) { |
26008
59d57ea69ae6
reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents:
26007
diff
changeset
|
517 PyErr_NoMemory(); |
26016
c8d41c9c23c7
reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents:
26015
diff
changeset
|
518 goto bail; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
519 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
520 |
26043
f2f0a3ab6e41
reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents:
26042
diff
changeset
|
521 revstates = (char *)calloc(len + 1, 1); |
f2f0a3ab6e41
reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents:
26042
diff
changeset
|
522 if (revstates == NULL) { |
26008
59d57ea69ae6
reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents:
26007
diff
changeset
|
523 PyErr_NoMemory(); |
26016
c8d41c9c23c7
reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents:
26015
diff
changeset
|
524 goto bail; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
525 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
526 |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
527 l = PyList_GET_SIZE(roots); |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
528 for (i = 0; i < l; i++) { |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
529 revnum = PyInt_AsLong(PyList_GET_ITEM(roots, i)); |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
530 if (revnum == -1 && PyErr_Occurred()) |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
531 goto bail; |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
532 /* If root is out of range, e.g. wdir(), it must be unreachable |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
533 * from heads. So we can just ignore it. */ |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
534 if (revnum + 1 < 0 || revnum + 1 >= len + 1) |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
535 continue; |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
536 revstates[revnum + 1] |= RS_ROOT; |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
537 } |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
538 |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
539 /* Populate tovisit with all the heads */ |
26042
2a3010ba6f52
reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents:
26041
diff
changeset
|
540 l = PyList_GET_SIZE(heads); |
2a3010ba6f52
reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents:
26041
diff
changeset
|
541 for (i = 0; i < l; i++) { |
26018
c6115c30a376
reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents:
26017
diff
changeset
|
542 revnum = PyInt_AsLong(PyList_GET_ITEM(heads, i)); |
c6115c30a376
reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents:
26017
diff
changeset
|
543 if (revnum == -1 && PyErr_Occurred()) |
c6115c30a376
reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents:
26017
diff
changeset
|
544 goto bail; |
26017
44705659da94
reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents:
26016
diff
changeset
|
545 if (revnum + 1 < 0 || revnum + 1 >= len + 1) { |
44705659da94
reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents:
26016
diff
changeset
|
546 PyErr_SetString(PyExc_IndexError, "head out of range"); |
44705659da94
reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents:
26016
diff
changeset
|
547 goto bail; |
44705659da94
reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents:
26016
diff
changeset
|
548 } |
26044
b3ad349d0e50
reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents:
26043
diff
changeset
|
549 if (!(revstates[revnum + 1] & RS_SEEN)) { |
26080
83c9edcac05c
reachableroots: silence warning of implicit integer narrowing issued by clang
Yuya Nishihara <yuya@tcha.org>
parents:
26079
diff
changeset
|
550 tovisit[lentovisit++] = (int)revnum; |
26044
b3ad349d0e50
reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents:
26043
diff
changeset
|
551 revstates[revnum + 1] |= RS_SEEN; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
552 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
553 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
554 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
555 /* Visit the tovisit list and find the reachable roots */ |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
556 k = 0; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
557 while (k < lentovisit) { |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
558 /* Add the node to reachable if it is a root*/ |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
559 revnum = tovisit[k++]; |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
560 if (revstates[revnum + 1] & RS_ROOT) { |
26054
5049e10fed14
reachableroots: use internal "revstates" array to test if rev is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26053
diff
changeset
|
561 revstates[revnum + 1] |= RS_REACHABLE; |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
562 val = PyInt_FromLong(revnum); |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
563 if (val == NULL) |
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
564 goto bail; |
26058
e7fe0a12376c
reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents:
26055
diff
changeset
|
565 r = PyList_Append(reachable, val); |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
566 Py_DECREF(val); |
26058
e7fe0a12376c
reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents:
26055
diff
changeset
|
567 if (r < 0) |
e7fe0a12376c
reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents:
26055
diff
changeset
|
568 goto bail; |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
569 if (includepath == 0) |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
570 continue; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
571 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
572 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
573 /* Add its parents to the list of nodes to visit */ |
26041
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
574 if (revnum == -1) |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
575 continue; |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
576 r = index_get_parents(self, revnum, parents, (int)len - 1); |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
577 if (r < 0) |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
578 goto bail; |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
579 for (i = 0; i < 2; i++) { |
26044
b3ad349d0e50
reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents:
26043
diff
changeset
|
580 if (!(revstates[parents[i] + 1] & RS_SEEN) |
26041
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
581 && parents[i] >= minroot) { |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
582 tovisit[lentovisit++] = parents[i]; |
26044
b3ad349d0e50
reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents:
26043
diff
changeset
|
583 revstates[parents[i] + 1] |= RS_SEEN; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
584 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
585 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
586 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
587 |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
588 /* Find all the nodes in between the roots we found and the heads |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
589 * and add them to the reachable set */ |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
590 if (includepath == 1) { |
26080
83c9edcac05c
reachableroots: silence warning of implicit integer narrowing issued by clang
Yuya Nishihara <yuya@tcha.org>
parents:
26079
diff
changeset
|
591 long minidx = minroot; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
592 if (minidx < 0) |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
593 minidx = 0; |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
594 for (i = minidx; i < len; i++) { |
26044
b3ad349d0e50
reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents:
26043
diff
changeset
|
595 if (!(revstates[i + 1] & RS_SEEN)) |
26041
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
596 continue; |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
597 r = index_get_parents(self, i, parents, (int)len - 1); |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
598 /* Corrupted index file, error is set from |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
599 * index_get_parents */ |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
600 if (r < 0) |
8da628be211b
reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents:
26033
diff
changeset
|
601 goto bail; |
26059
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
602 if (((revstates[parents[0] + 1] | |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
603 revstates[parents[1] + 1]) & RS_REACHABLE) |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
604 && !(revstates[i + 1] & RS_REACHABLE)) { |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
605 revstates[i + 1] |= RS_REACHABLE; |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
606 val = PyInt_FromLong(i); |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
607 if (val == NULL) |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
608 goto bail; |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
609 r = PyList_Append(reachable, val); |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
610 Py_DECREF(val); |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
611 if (r < 0) |
8779ce81ea80
reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents:
26058
diff
changeset
|
612 goto bail; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
613 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
614 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
615 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
616 |
26043
f2f0a3ab6e41
reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents:
26042
diff
changeset
|
617 free(revstates); |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
618 free(tovisit); |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
619 return reachable; |
26016
c8d41c9c23c7
reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents:
26015
diff
changeset
|
620 bail: |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
621 Py_XDECREF(reachable); |
26043
f2f0a3ab6e41
reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents:
26042
diff
changeset
|
622 free(revstates); |
26016
c8d41c9c23c7
reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents:
26015
diff
changeset
|
623 free(tovisit); |
26010
2c03e521a0c5
reachableroots: return NULL if we're throwing an exception
Augie Fackler <augie@google.com>
parents:
26009
diff
changeset
|
624 return NULL; |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
625 } |
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
626 |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
627 static PyObject *compute_phases_map_sets(indexObject *self, PyObject *args) |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
628 { |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
629 PyObject *roots = Py_None; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
630 PyObject *ret = NULL; |
35309
d13526333835
phases: drop the list with phase of each rev, always comput phase sets
Joerg Sonnenberger <joerg@bec.de>
parents:
34861
diff
changeset
|
631 PyObject *phasessize = NULL; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
632 PyObject *phaseroots = NULL; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
633 PyObject *phaseset = NULL; |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
634 PyObject *phasessetlist = NULL; |
25911
f4386cb3252e
parsers: fix memory leak in compute_phases_map_sets
Laurent Charignon <lcharignon@fb.com>
parents:
25860
diff
changeset
|
635 PyObject *rev = NULL; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
636 Py_ssize_t len = index_length(self) - 1; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
637 Py_ssize_t numphase = 0; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
638 Py_ssize_t minrevallphases = 0; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
639 Py_ssize_t minrevphase = 0; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
640 Py_ssize_t i = 0; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
641 char *phases = NULL; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
642 long phase; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
643 |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
644 if (!PyArg_ParseTuple(args, "O", &roots)) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
645 goto done; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
646 if (roots == NULL || !PyList_Check(roots)) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
647 goto done; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
648 |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
649 phases = calloc(len, 1); /* phase per rev: {0: public, 1: draft, 2: secret} */ |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
650 if (phases == NULL) { |
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
651 PyErr_NoMemory(); |
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
652 goto done; |
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
653 } |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
654 /* Put the phase information of all the roots in phases */ |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
655 numphase = PyList_GET_SIZE(roots)+1; |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
656 minrevallphases = len + 1; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
657 phasessetlist = PyList_New(numphase); |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
658 if (phasessetlist == NULL) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
659 goto done; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
660 |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
661 PyList_SET_ITEM(phasessetlist, 0, Py_None); |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
662 Py_INCREF(Py_None); |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
663 |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
664 for (i = 0; i < numphase-1; i++) { |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
665 phaseroots = PyList_GET_ITEM(roots, i); |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
666 phaseset = PySet_New(NULL); |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
667 if (phaseset == NULL) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
668 goto release; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
669 PyList_SET_ITEM(phasessetlist, i+1, phaseset); |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
670 if (!PyList_Check(phaseroots)) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
671 goto release; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
672 minrevphase = add_roots_get_min(self, phaseroots, i+1, phases); |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
673 if (minrevphase == -2) /* Error from add_roots_get_min */ |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
674 goto release; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
675 minrevallphases = MIN(minrevallphases, minrevphase); |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
676 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
677 /* Propagate the phase information from the roots to the revs */ |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
678 if (minrevallphases != -1) { |
25312
ee02728dd5f9
parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents:
25311
diff
changeset
|
679 int parents[2]; |
ee02728dd5f9
parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents:
25311
diff
changeset
|
680 for (i = minrevallphases; i < len; i++) { |
25860
895f04955a49
parsers: silence warning of implicit integer conversion issued by clang
Yuya Nishihara <yuya@tcha.org>
parents:
25810
diff
changeset
|
681 if (index_get_parents(self, i, parents, |
895f04955a49
parsers: silence warning of implicit integer conversion issued by clang
Yuya Nishihara <yuya@tcha.org>
parents:
25810
diff
changeset
|
682 (int)len - 1) < 0) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
683 goto release; |
25312
ee02728dd5f9
parsers: simplify the code computing the phases
Laurent Charignon <lcharignon@fb.com>
parents:
25311
diff
changeset
|
684 set_phase_from_parents(phases, parents[0], parents[1], i); |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
685 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
686 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
687 /* Transform phase list to a python list */ |
35309
d13526333835
phases: drop the list with phase of each rev, always comput phase sets
Joerg Sonnenberger <joerg@bec.de>
parents:
34861
diff
changeset
|
688 phasessize = PyInt_FromLong(len); |
d13526333835
phases: drop the list with phase of each rev, always comput phase sets
Joerg Sonnenberger <joerg@bec.de>
parents:
34861
diff
changeset
|
689 if (phasessize == NULL) |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
690 goto release; |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
691 for (i = 0; i < len; i++) { |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
692 phase = phases[i]; |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
693 /* We only store the sets of phase for non public phase, the public phase |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
694 * is computed as a difference */ |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
695 if (phase != 0) { |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
696 phaseset = PyList_GET_ITEM(phasessetlist, phase); |
25911
f4386cb3252e
parsers: fix memory leak in compute_phases_map_sets
Laurent Charignon <lcharignon@fb.com>
parents:
25860
diff
changeset
|
697 rev = PyInt_FromLong(i); |
27365
ec04370bdfaf
parsers: check results of PyInt_FromLong (issue4771)
Bryan O'Sullivan <bos@serpentine.com>
parents:
27364
diff
changeset
|
698 if (rev == NULL) |
ec04370bdfaf
parsers: check results of PyInt_FromLong (issue4771)
Bryan O'Sullivan <bos@serpentine.com>
parents:
27364
diff
changeset
|
699 goto release; |
25911
f4386cb3252e
parsers: fix memory leak in compute_phases_map_sets
Laurent Charignon <lcharignon@fb.com>
parents:
25860
diff
changeset
|
700 PySet_Add(phaseset, rev); |
f4386cb3252e
parsers: fix memory leak in compute_phases_map_sets
Laurent Charignon <lcharignon@fb.com>
parents:
25860
diff
changeset
|
701 Py_XDECREF(rev); |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
702 } |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
703 } |
35309
d13526333835
phases: drop the list with phase of each rev, always comput phase sets
Joerg Sonnenberger <joerg@bec.de>
parents:
34861
diff
changeset
|
704 ret = PyTuple_Pack(2, phasessize, phasessetlist); |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
705 |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
706 release: |
35309
d13526333835
phases: drop the list with phase of each rev, always comput phase sets
Joerg Sonnenberger <joerg@bec.de>
parents:
34861
diff
changeset
|
707 Py_XDECREF(phasessize); |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
708 Py_XDECREF(phasessetlist); |
27364
ad1cc1435b13
parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents:
27341
diff
changeset
|
709 done: |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
710 free(phases); |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
711 return ret; |
24443
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
712 } |
539b3c7eea44
phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents:
24214
diff
changeset
|
713 |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
714 static PyObject *index_headrevs(indexObject *self, PyObject *args) |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
715 { |
25297
3966e39fea98
changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents:
25296
diff
changeset
|
716 Py_ssize_t i, j, len; |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
717 char *nothead = NULL; |
22540
9a860ac8c216
parsers: fix uninitialize variable warning
David Soria Parra <davidsp@fb.com>
parents:
22484
diff
changeset
|
718 PyObject *heads = NULL; |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
719 PyObject *filter = NULL; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
720 PyObject *filteredrevs = Py_None; |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
721 |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
722 if (!PyArg_ParseTuple(args, "|O", &filteredrevs)) { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
723 return NULL; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
724 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
725 |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
726 if (self->headrevs && filteredrevs == self->filteredrevs) |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
727 return list_copy(self->headrevs); |
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
728 |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
729 Py_DECREF(self->filteredrevs); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
730 self->filteredrevs = filteredrevs; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
731 Py_INCREF(filteredrevs); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
732 |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
733 if (filteredrevs != Py_None) { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
734 filter = PyObject_GetAttrString(filteredrevs, "__contains__"); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
735 if (!filter) { |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
736 PyErr_SetString(PyExc_TypeError, |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
737 "filteredrevs has no attribute __contains__"); |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
738 goto bail; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
739 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
740 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
741 |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
742 len = index_length(self) - 1; |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
743 heads = PyList_New(0); |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
744 if (heads == NULL) |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
745 goto bail; |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
746 if (len == 0) { |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
747 PyObject *nullid = PyInt_FromLong(-1); |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
748 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
|
749 Py_XDECREF(nullid); |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
750 goto bail; |
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 goto done; |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
753 } |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
754 |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
755 nothead = calloc(len, 1); |
27366
7e8a883da171
parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents:
27365
diff
changeset
|
756 if (nothead == NULL) { |
7e8a883da171
parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents:
27365
diff
changeset
|
757 PyErr_NoMemory(); |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
758 goto bail; |
27366
7e8a883da171
parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents:
27365
diff
changeset
|
759 } |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
760 |
28386
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
761 for (i = len - 1; i >= 0; i--) { |
25297
3966e39fea98
changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents:
25296
diff
changeset
|
762 int isfiltered; |
3966e39fea98
changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents:
25296
diff
changeset
|
763 int parents[2]; |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
764 |
28386
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
765 /* If nothead[i] == 1, it means we've seen an unfiltered child of this |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
766 * node already, and therefore this node is not filtered. So we can skip |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
767 * the expensive check_filter step. |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
768 */ |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
769 if (nothead[i] != 1) { |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
770 isfiltered = check_filter(filter, i); |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
771 if (isfiltered == -1) { |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
772 PyErr_SetString(PyExc_TypeError, |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
773 "unable to check filter"); |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
774 goto bail; |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
775 } |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
776 |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
777 if (isfiltered) { |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
778 nothead[i] = 1; |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
779 continue; |
1c658391b22f
parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents:
27638
diff
changeset
|
780 } |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
781 } |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
782 |
25860
895f04955a49
parsers: silence warning of implicit integer conversion issued by clang
Yuya Nishihara <yuya@tcha.org>
parents:
25810
diff
changeset
|
783 if (index_get_parents(self, i, parents, (int)len - 1) < 0) |
25810
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
784 goto bail; |
25297
3966e39fea98
changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents:
25296
diff
changeset
|
785 for (j = 0; j < 2; j++) { |
3966e39fea98
changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents:
25296
diff
changeset
|
786 if (parents[j] >= 0) |
3966e39fea98
changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents:
25296
diff
changeset
|
787 nothead[parents[j]] = 1; |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
788 } |
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 |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
791 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
|
792 PyObject *head; |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
793 |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
794 if (nothead[i]) |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
795 continue; |
22400
888bc106de83
parsers: fix typing issue when constructing Python integer object
Henrik Stuart <hg@hstuart.dk>
parents:
22399
diff
changeset
|
796 head = PyInt_FromSsize_t(i); |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
797 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
|
798 Py_XDECREF(head); |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
799 goto bail; |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
800 } |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
801 } |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
802 |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
803 done: |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
804 self->headrevs = heads; |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
805 Py_XDECREF(filter); |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
806 free(nothead); |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
807 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
|
808 bail: |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
809 Py_XDECREF(filter); |
16786
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
810 Py_XDECREF(heads); |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
811 free(nothead); |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
812 return NULL; |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
813 } |
2631cd5dd244
revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16784
diff
changeset
|
814 |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
815 /** |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
816 * Obtain the base revision index entry. |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
817 * |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
818 * Callers must ensure that rev >= 0 or illegal memory access may occur. |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
819 */ |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
820 static inline int index_baserev(indexObject *self, int rev) |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
821 { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
822 const char *data; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
823 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
824 if (rev >= self->length - 1) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
825 PyObject *tuple = PyList_GET_ITEM(self->added, |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
826 rev - self->length + 1); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
827 return (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3)); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
828 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
829 else { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
830 data = index_deref(self, rev); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
831 if (data == NULL) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
832 return -2; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
833 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
834 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
835 return getbe32(data + 16); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
836 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
837 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
838 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
839 static PyObject *index_deltachain(indexObject *self, PyObject *args) |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
840 { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
841 int rev, generaldelta; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
842 PyObject *stoparg; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
843 int stoprev, iterrev, baserev = -1; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
844 int stopped; |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
845 PyObject *chain = NULL, *result = NULL; |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
846 const Py_ssize_t length = index_length(self); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
847 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
848 if (!PyArg_ParseTuple(args, "iOi", &rev, &stoparg, &generaldelta)) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
849 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
850 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
851 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
852 if (PyInt_Check(stoparg)) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
853 stoprev = (int)PyInt_AsLong(stoparg); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
854 if (stoprev == -1 && PyErr_Occurred()) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
855 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
856 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
857 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
858 else if (stoparg == Py_None) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
859 stoprev = -2; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
860 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
861 else { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
862 PyErr_SetString(PyExc_ValueError, |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
863 "stoprev must be integer or None"); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
864 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
865 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
866 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
867 if (rev < 0 || rev >= length - 1) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
868 PyErr_SetString(PyExc_ValueError, "revlog index out of range"); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
869 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
870 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
871 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
872 chain = PyList_New(0); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
873 if (chain == NULL) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
874 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
875 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
876 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
877 baserev = index_baserev(self, rev); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
878 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
879 /* This should never happen. */ |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
880 if (baserev <= -2) { |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
881 /* Error should be set by index_deref() */ |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
882 assert(PyErr_Occurred()); |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
883 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
884 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
885 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
886 iterrev = rev; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
887 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
888 while (iterrev != baserev && iterrev != stoprev) { |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
889 PyObject *value = PyInt_FromLong(iterrev); |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
890 if (value == NULL) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
891 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
892 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
893 if (PyList_Append(chain, value)) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
894 Py_DECREF(value); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
895 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
896 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
897 Py_DECREF(value); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
898 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
899 if (generaldelta) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
900 iterrev = baserev; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
901 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
902 else { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
903 iterrev--; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
904 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
905 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
906 if (iterrev < 0) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
907 break; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
908 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
909 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
910 if (iterrev >= length - 1) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
911 PyErr_SetString(PyExc_IndexError, "revision outside index"); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
912 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
913 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
914 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
915 baserev = index_baserev(self, iterrev); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
916 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
917 /* This should never happen. */ |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
918 if (baserev <= -2) { |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
919 /* Error should be set by index_deref() */ |
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
920 assert(PyErr_Occurred()); |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
921 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
922 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
923 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
924 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
925 if (iterrev == stoprev) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
926 stopped = 1; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
927 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
928 else { |
33174
f4f52bb362e6
revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
33171
diff
changeset
|
929 PyObject *value = PyInt_FromLong(iterrev); |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
930 if (value == NULL) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
931 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
932 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
933 if (PyList_Append(chain, value)) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
934 Py_DECREF(value); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
935 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
936 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
937 Py_DECREF(value); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
938 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
939 stopped = 0; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
940 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
941 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
942 if (PyList_Reverse(chain)) { |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
943 goto bail; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
944 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
945 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
946 result = Py_BuildValue("OO", chain, stopped ? Py_True : Py_False); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
947 Py_DECREF(chain); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
948 return result; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
949 |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
950 bail: |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
951 Py_DECREF(chain); |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
952 return NULL; |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
953 } |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
954 |
16618
6bae941b58ad
parsers: change the type of nt_level
Bryan O'Sullivan <bryano@fb.com>
parents:
16617
diff
changeset
|
955 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
|
956 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
957 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
|
958 if (!(level & 1)) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
959 v >>= 4; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
960 return v & 0xf; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
961 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
962 |
16616
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
963 /* |
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
964 * Return values: |
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
965 * |
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
966 * -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
|
967 * -2: not found |
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
968 * rest: valid rev |
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
969 */ |
16663 | 970 static int nt_find(indexObject *self, const char *node, Py_ssize_t nodelen, |
971 int hex) | |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
972 { |
16663 | 973 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
|
974 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
|
975 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
976 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
|
977 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
978 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
979 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
|
980 return -2; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
981 |
16663 | 982 if (hex) |
16665
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
983 maxlevel = nodelen > 40 ? 40 : (int)nodelen; |
16663 | 984 else |
985 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
|
986 |
e6dfbc5df76f
parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents:
16604
diff
changeset
|
987 for (level = off = 0; level < maxlevel; level++) { |
16663 | 988 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
|
989 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
|
990 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
|
991 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
992 if (v < 0) { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
993 const char *n; |
16663 | 994 Py_ssize_t i; |
995 | |
24879
b3142ea2a0d4
parsers: avoid signed integer overflow in calculation of leaf-node index
Yuya Nishihara <yuya@tcha.org>
parents:
24736
diff
changeset
|
996 v = -(v + 1); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
997 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
|
998 if (n == NULL) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
999 return -2; |
16663 | 1000 for (i = level; i < maxlevel; i++) |
1001 if (getnybble(node, i) != nt_level(n, i)) | |
1002 return -2; | |
1003 return v; | |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1004 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1005 if (v == 0) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1006 return -2; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1007 off = v; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1008 } |
16616
8f79aabd96f6
parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents:
16615
diff
changeset
|
1009 /* 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
|
1010 return -4; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1011 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1012 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1013 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
|
1014 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1015 if (self->ntlength == self->ntcapacity) { |
24623
2262d7bc469e
parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents:
24622
diff
changeset
|
1016 if (self->ntcapacity >= INT_MAX / (sizeof(nodetree) * 2)) { |
2262d7bc469e
parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents:
24622
diff
changeset
|
1017 PyErr_SetString(PyExc_MemoryError, |
2262d7bc469e
parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents:
24622
diff
changeset
|
1018 "overflow in nt_new"); |
2262d7bc469e
parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents:
24622
diff
changeset
|
1019 return -1; |
2262d7bc469e
parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents:
24622
diff
changeset
|
1020 } |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1021 self->ntcapacity *= 2; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1022 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
|
1023 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
|
1024 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
|
1025 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
|
1026 return -1; |
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 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
|
1029 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
|
1030 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1031 return self->ntlength++; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1032 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1033 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1034 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
|
1035 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1036 int level = 0; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1037 int off = 0; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1038 |
16641
e6dfbc5df76f
parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents:
16604
diff
changeset
|
1039 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
|
1040 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
|
1041 nodetree *n; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1042 int v; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1043 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1044 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
|
1045 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
|
1046 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1047 if (v == 0) { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1048 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
|
1049 return 0; |
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 if (v < 0) { |
24879
b3142ea2a0d4
parsers: avoid signed integer overflow in calculation of leaf-node index
Yuya Nishihara <yuya@tcha.org>
parents:
24736
diff
changeset
|
1052 const char *oldnode = index_node(self, -(v + 1)); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1053 int noff; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1054 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1055 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
|
1056 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
|
1057 return 0; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1058 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1059 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
|
1060 if (noff == -1) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1061 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1062 /* 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
|
1063 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
|
1064 off = noff; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1065 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
|
1066 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
|
1067 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
|
1068 self->ntdepth = level; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1069 self->ntsplits += 1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1070 } else { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1071 level += 1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1072 off = v; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1073 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1074 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1075 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1076 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1077 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1078 |
16615
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1079 static int nt_init(indexObject *self) |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1080 { |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1081 if (self->nt == NULL) { |
26775
3c259710737c
parsers: suppress warning of signed and unsigned comparison at nt_init
Yuya Nishihara <yuya@tcha.org>
parents:
26774
diff
changeset
|
1082 if ((size_t)self->raw_length > INT_MAX / sizeof(nodetree)) { |
20110
40b7c6e4b993
mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents:
19728
diff
changeset
|
1083 PyErr_SetString(PyExc_ValueError, "overflow in nt_init"); |
40b7c6e4b993
mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents:
19728
diff
changeset
|
1084 return -1; |
40b7c6e4b993
mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents:
19728
diff
changeset
|
1085 } |
16615
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1086 self->ntcapacity = self->raw_length < 4 |
20110
40b7c6e4b993
mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents:
19728
diff
changeset
|
1087 ? 4 : (int)self->raw_length / 2; |
40b7c6e4b993
mercurial/parsers.c: fix compiler warning
Abhay Kadam <abhaykadam88@gmail.com>
parents:
19728
diff
changeset
|
1088 |
16615
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1089 self->nt = calloc(self->ntcapacity, sizeof(nodetree)); |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1090 if (self->nt == NULL) { |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1091 PyErr_NoMemory(); |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1092 return -1; |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1093 } |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1094 self->ntlength = 1; |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1095 self->ntrev = (int)index_length(self) - 1; |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1096 self->ntlookups = 1; |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1097 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
|
1098 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
|
1099 return -1; |
16615
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1100 } |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1101 return 0; |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1102 } |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1103 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1104 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1105 * Return values: |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1106 * |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1107 * -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
|
1108 * -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
|
1109 * rest: valid rev |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1110 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1111 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
|
1112 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
|
1113 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1114 int rev; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1115 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1116 self->ntlookups++; |
16663 | 1117 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
|
1118 if (rev >= -1) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1119 return rev; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1120 |
16615
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1121 if (nt_init(self) == -1) |
96fa9dd1db38
parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents:
16614
diff
changeset
|
1122 return -3; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1123 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1124 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1125 * 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
|
1126 * 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
|
1127 * 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
|
1128 * |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1129 * 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
|
1130 * 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
|
1131 * 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
|
1132 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1133 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
|
1134 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
|
1135 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
|
1136 if (n == NULL) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1137 return -2; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1138 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
|
1139 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
|
1140 return -3; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1141 break; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1142 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1143 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1144 } else { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1145 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
|
1146 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
|
1147 if (n == NULL) { |
1d800eb9ba52
parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents:
16597
diff
changeset
|
1148 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
|
1149 return -2; |
16614
1d800eb9ba52
parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents:
16597
diff
changeset
|
1150 } |
1d800eb9ba52
parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents:
16597
diff
changeset
|
1151 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
|
1152 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
|
1153 return -3; |
16614
1d800eb9ba52
parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents:
16597
diff
changeset
|
1154 } |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1155 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
|
1156 break; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1157 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1158 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1159 self->ntrev = rev; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1160 } |
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 if (rev >= 0) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1163 return rev; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1164 return -2; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1165 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1166 |
25561
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1167 static void raise_revlog_error(void) |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1168 { |
25561
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1169 PyObject *mod = NULL, *dict = NULL, *errclass = NULL; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1170 |
25561
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1171 mod = PyImport_ImportModule("mercurial.error"); |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1172 if (mod == NULL) { |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1173 goto cleanup; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1174 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1175 |
25561
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1176 dict = PyModule_GetDict(mod); |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1177 if (dict == NULL) { |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1178 goto cleanup; |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1179 } |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1180 Py_INCREF(dict); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1181 |
25561
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1182 errclass = PyDict_GetItemString(dict, "RevlogError"); |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1183 if (errclass == NULL) { |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1184 PyErr_SetString(PyExc_SystemError, |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1185 "could not find RevlogError"); |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1186 goto cleanup; |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1187 } |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1188 |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1189 /* value of exception is ignored by callers */ |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1190 PyErr_SetString(errclass, "RevlogError"); |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1191 |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1192 cleanup: |
50a6c3c55db1
parsers: do not cache RevlogError type (issue4451)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
24879
diff
changeset
|
1193 Py_XDECREF(dict); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1194 Py_XDECREF(mod); |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1195 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1196 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1197 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
|
1198 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1199 char *node; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1200 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
|
1201 int rev; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1202 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1203 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
|
1204 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
|
1205 |
16679
2950d186a927
parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents:
16641
diff
changeset
|
1206 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
|
1207 return NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1208 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
|
1209 if (rev >= -1) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1210 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
|
1211 if (rev == -2) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1212 raise_revlog_error(); |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1213 return NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1214 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1215 |
16665
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1216 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
|
1217 Py_ssize_t nodelen) |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1218 { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1219 int rev; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1220 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1221 if (nt_init(self) == -1) |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1222 return -3; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1223 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1224 if (self->ntrev > 0) { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1225 /* 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
|
1226 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
|
1227 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
|
1228 if (n == NULL) |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1229 return -2; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1230 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
|
1231 return -3; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1232 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1233 self->ntrev = rev; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1234 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1235 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1236 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
|
1237 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1238 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1239 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
|
1240 { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1241 const char *fullnode; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1242 int nodelen; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1243 char *node; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1244 int rev, i; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1245 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1246 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
|
1247 return NULL; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1248 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1249 if (nodelen < 4) { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1250 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
|
1251 return NULL; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1252 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1253 |
17353
bde1185f406c
revlog: don't try to partialmatch strings those length > 40
sorcerer
parents:
17165
diff
changeset
|
1254 if (nodelen > 40) { |
bde1185f406c
revlog: don't try to partialmatch strings those length > 40
sorcerer
parents:
17165
diff
changeset
|
1255 PyErr_SetString(PyExc_ValueError, "key too long"); |
bde1185f406c
revlog: don't try to partialmatch strings those length > 40
sorcerer
parents:
17165
diff
changeset
|
1256 return NULL; |
bde1185f406c
revlog: don't try to partialmatch strings those length > 40
sorcerer
parents:
17165
diff
changeset
|
1257 } |
16665
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1258 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1259 for (i = 0; i < nodelen; i++) |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1260 hexdigit(node, i); |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1261 if (PyErr_Occurred()) { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1262 /* input contains non-hex characters */ |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1263 PyErr_Clear(); |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1264 Py_RETURN_NONE; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1265 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1266 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1267 rev = nt_partialmatch(self, node, nodelen); |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1268 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1269 switch (rev) { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1270 case -4: |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1271 raise_revlog_error(); |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1272 case -3: |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1273 return NULL; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1274 case -2: |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1275 Py_RETURN_NONE; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1276 case -1: |
30100
c5afe5531709
parsers: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30090
diff
changeset
|
1277 return PyBytes_FromStringAndSize(nullid, 20); |
16665
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1278 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1279 |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1280 fullnode = index_node(self, rev); |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1281 if (fullnode == NULL) { |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1282 PyErr_Format(PyExc_IndexError, |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1283 "could not access rev %d", rev); |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1284 return NULL; |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1285 } |
30100
c5afe5531709
parsers: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30090
diff
changeset
|
1286 return PyBytes_FromStringAndSize(fullnode, 20); |
16665
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1287 } |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1288 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1289 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
|
1290 { |
16679
2950d186a927
parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents:
16641
diff
changeset
|
1291 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
|
1292 PyObject *val; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1293 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
|
1294 int rev; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1295 |
16679
2950d186a927
parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents:
16641
diff
changeset
|
1296 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
|
1297 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
|
1298 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
|
1299 return NULL; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1300 rev = index_find_node(self, node, nodelen); |
27638
90e3c5129226
cleanup: remove superfluous space after space after equals (C)
timeless <timeless@mozdev.org>
parents:
27592
diff
changeset
|
1301 if (rev == -3) |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1302 return NULL; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1303 if (rev == -2) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1304 Py_RETURN_NONE; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1305 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
|
1306 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1307 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1308 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
|
1309 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1310 char *node; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1311 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
|
1312 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1313 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
|
1314 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
|
1315 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
|
1316 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1317 |
16679
2950d186a927
parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents:
16641
diff
changeset
|
1318 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
|
1319 return -1; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1320 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1321 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
|
1322 case -3: |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1323 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1324 case -2: |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1325 return 0; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1326 default: |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1327 return 1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1328 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1329 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1330 |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1331 typedef uint64_t bitmask; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1332 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1333 /* |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1334 * 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
|
1335 * 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
|
1336 * "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
|
1337 */ |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1338 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
|
1339 int revcount) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1340 { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1341 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
|
1342 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
|
1343 PyObject *gca = PyList_New(0); |
20555
4add43865a9b
ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents:
20554
diff
changeset
|
1344 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
|
1345 int maxrev = -1; |
22399
9f490afcb067
parsers: use bitmask type consistently in find_gca_candidates
Henrik Stuart <hg@hstuart.dk>
parents:
21871
diff
changeset
|
1346 bitmask sp; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1347 bitmask *seen; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1348 |
19727
3d07b4a2f743
parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents:
19726
diff
changeset
|
1349 if (gca == NULL) |
3d07b4a2f743
parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents:
19726
diff
changeset
|
1350 return PyErr_NoMemory(); |
3d07b4a2f743
parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents:
19726
diff
changeset
|
1351 |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1352 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
|
1353 if (revs[i] > maxrev) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1354 maxrev = revs[i]; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1355 } |
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 seen = calloc(sizeof(*seen), maxrev + 1); |
19727
3d07b4a2f743
parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents:
19726
diff
changeset
|
1358 if (seen == NULL) { |
3d07b4a2f743
parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents:
19726
diff
changeset
|
1359 Py_DECREF(gca); |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1360 return PyErr_NoMemory(); |
19727
3d07b4a2f743
parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents:
19726
diff
changeset
|
1361 } |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1362 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1363 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
|
1364 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
|
1365 |
20555
4add43865a9b
ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents:
20554
diff
changeset
|
1366 interesting = revcount; |
18988
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 for (v = maxrev; v >= 0 && interesting; v--) { |
22399
9f490afcb067
parsers: use bitmask type consistently in find_gca_candidates
Henrik Stuart <hg@hstuart.dk>
parents:
21871
diff
changeset
|
1369 bitmask sv = seen[v]; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1370 int parents[2]; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1371 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1372 if (!sv) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1373 continue; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1374 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1375 if (sv < poison) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1376 interesting -= 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1377 if (sv == allseen) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1378 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
|
1379 if (obj == NULL) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1380 goto bail; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1381 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
|
1382 Py_DECREF(obj); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1383 goto bail; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1384 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1385 sv |= poison; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1386 for (i = 0; i < revcount; i++) { |
20555
4add43865a9b
ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents:
20554
diff
changeset
|
1387 if (revs[i] == v) |
4add43865a9b
ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents:
20554
diff
changeset
|
1388 goto done; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1389 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1390 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1391 } |
25810
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
1392 if (index_get_parents(self, v, parents, maxrev) < 0) |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
1393 goto bail; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1394 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1395 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
|
1396 int p = parents[i]; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1397 if (p == -1) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1398 continue; |
19030
48d6f436363e
parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents:
18988
diff
changeset
|
1399 sp = seen[p]; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1400 if (sv < poison) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1401 if (sp == 0) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1402 seen[p] = sv; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1403 interesting++; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1404 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1405 else if (sp != sv) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1406 seen[p] |= sv; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1407 } else { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1408 if (sp && sp < poison) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1409 interesting--; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1410 seen[p] = sv; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1411 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1412 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1413 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1414 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1415 done: |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1416 free(seen); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1417 return gca; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1418 bail: |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1419 free(seen); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1420 Py_XDECREF(gca); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1421 return NULL; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1422 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1423 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1424 /* |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1425 * 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
|
1426 * path to the root. |
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 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
|
1429 { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1430 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
|
1431 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
|
1432 int *depth, *interesting = NULL; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1433 int i, j, v, ninteresting; |
21730
8da100383dc3
parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents:
21103
diff
changeset
|
1434 PyObject *dict = NULL, *keys = NULL; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1435 long *seen = NULL; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1436 int maxrev = -1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1437 long final; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1438 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1439 if (revcount > capacity) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1440 PyErr_Format(PyExc_OverflowError, |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1441 "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
|
1442 (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
|
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 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
|
1447 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
|
1448 if (n > maxrev) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1449 maxrev = n; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1450 } |
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 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
|
1453 if (depth == NULL) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1454 return PyErr_NoMemory(); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1455 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1456 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
|
1457 if (seen == NULL) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1458 PyErr_NoMemory(); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1459 goto bail; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1460 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1461 |
33475
f501322512b6
parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents:
33174
diff
changeset
|
1462 interesting = calloc(sizeof(*interesting), 1 << revcount); |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1463 if (interesting == NULL) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1464 PyErr_NoMemory(); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1465 goto bail; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1466 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1467 |
19502
8704477ad3b6
ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents:
19062
diff
changeset
|
1468 if (PyList_Sort(revs) == -1) |
8704477ad3b6
ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents:
19062
diff
changeset
|
1469 goto bail; |
8704477ad3b6
ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents:
19062
diff
changeset
|
1470 |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1471 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
|
1472 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
|
1473 long b = 1l << i; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1474 depth[n] = 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1475 seen[n] = b; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1476 interesting[b] = 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1477 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1478 |
33475
f501322512b6
parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents:
33174
diff
changeset
|
1479 /* invariant: ninteresting is the number of non-zero entries in |
f501322512b6
parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents:
33174
diff
changeset
|
1480 * interesting. */ |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1481 ninteresting = (int)revcount; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1482 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1483 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
|
1484 int dv = depth[v]; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1485 int parents[2]; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1486 long sv; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1487 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1488 if (dv == 0) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1489 continue; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1490 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1491 sv = seen[v]; |
25810
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
1492 if (index_get_parents(self, v, parents, maxrev) < 0) |
82d6a35cf432
parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents:
25584
diff
changeset
|
1493 goto bail; |
18988
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 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
|
1496 int p = parents[i]; |
27341
5042b999ef0a
parsers: narrow scope of a variable to be less confusing
Bryan O'Sullivan <bos@serpentine.com>
parents:
27226
diff
changeset
|
1497 long sp; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1498 int dp; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1499 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1500 if (p == -1) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1501 continue; |
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 dp = depth[p]; |
27341
5042b999ef0a
parsers: narrow scope of a variable to be less confusing
Bryan O'Sullivan <bos@serpentine.com>
parents:
27226
diff
changeset
|
1504 sp = seen[p]; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1505 if (dp <= dv) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1506 depth[p] = dv + 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1507 if (sp != sv) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1508 interesting[sv] += 1; |
27341
5042b999ef0a
parsers: narrow scope of a variable to be less confusing
Bryan O'Sullivan <bos@serpentine.com>
parents:
27226
diff
changeset
|
1509 seen[p] = sv; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1510 if (sp) { |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1511 interesting[sp] -= 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1512 if (interesting[sp] == 0) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1513 ninteresting -= 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1514 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1515 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1516 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1517 else if (dv == dp - 1) { |
27341
5042b999ef0a
parsers: narrow scope of a variable to be less confusing
Bryan O'Sullivan <bos@serpentine.com>
parents:
27226
diff
changeset
|
1518 long nsp = sp | sv; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1519 if (nsp == sp) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1520 continue; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1521 seen[p] = nsp; |
19503
f2dfda6ac152
ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents:
19502
diff
changeset
|
1522 interesting[sp] -= 1; |
33475
f501322512b6
parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents:
33174
diff
changeset
|
1523 if (interesting[sp] == 0) |
19503
f2dfda6ac152
ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents:
19502
diff
changeset
|
1524 ninteresting -= 1; |
33475
f501322512b6
parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents:
33174
diff
changeset
|
1525 if (interesting[nsp] == 0) |
f501322512b6
parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents:
33174
diff
changeset
|
1526 ninteresting += 1; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1527 interesting[nsp] += 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1528 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1529 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1530 interesting[sv] -= 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1531 if (interesting[sv] == 0) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1532 ninteresting -= 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1533 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1534 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1535 final = 0; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1536 j = ninteresting; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1537 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
|
1538 if (interesting[i] == 0) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1539 continue; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1540 final |= i; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1541 j -= 1; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1542 } |
21730
8da100383dc3
parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents:
21103
diff
changeset
|
1543 if (final == 0) { |
8da100383dc3
parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents:
21103
diff
changeset
|
1544 keys = PyList_New(0); |
8da100383dc3
parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents:
21103
diff
changeset
|
1545 goto bail; |
8da100383dc3
parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents:
21103
diff
changeset
|
1546 } |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1547 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1548 dict = PyDict_New(); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1549 if (dict == NULL) |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1550 goto bail; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1551 |
19504
2fa303619b4d
ancestor.deepest: ignore ninteresting while building result (issue3984)
Siddharth Agarwal <sid0@fb.com>
parents:
19503
diff
changeset
|
1552 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
|
1553 PyObject *key; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1554 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1555 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
|
1556 continue; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1557 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1558 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
|
1559 Py_INCREF(key); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1560 Py_INCREF(Py_None); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1561 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
|
1562 Py_DECREF(key); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1563 Py_DECREF(Py_None); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1564 goto bail; |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1565 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1566 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1567 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1568 keys = PyDict_Keys(dict); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1569 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1570 bail: |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1571 free(depth); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1572 free(seen); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1573 free(interesting); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1574 Py_XDECREF(dict); |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1575 |
21730
8da100383dc3
parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents:
21103
diff
changeset
|
1576 return keys; |
18988
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1577 } |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1578 |
5bae936764bb
parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents:
18900
diff
changeset
|
1579 /* |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1580 * Given a (possibly overlapping) set of revs, return all the |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1581 * common ancestors heads: heads(::args[0] and ::a[1] and ...) |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1582 */ |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1583 static PyObject *index_commonancestorsheads(indexObject *self, PyObject *args) |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1584 { |
21103
628c16489d1c
parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
21102
diff
changeset
|
1585 PyObject *ret = NULL; |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1586 Py_ssize_t argcount, i, len; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1587 bitmask repeat = 0; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1588 int revcount = 0; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1589 int *revs; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1590 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1591 argcount = PySequence_Length(args); |
31469
a43fd9ec2a39
parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31426
diff
changeset
|
1592 revs = PyMem_Malloc(argcount * sizeof(*revs)); |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1593 if (argcount > 0 && revs == NULL) |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1594 return PyErr_NoMemory(); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1595 len = index_length(self) - 1; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1596 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1597 for (i = 0; i < argcount; i++) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1598 static const int capacity = 24; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1599 PyObject *obj = PySequence_GetItem(args, i); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1600 bitmask x; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1601 long val; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1602 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1603 if (!PyInt_Check(obj)) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1604 PyErr_SetString(PyExc_TypeError, |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1605 "arguments must all be ints"); |
23945
33d6aaf84c9e
parsers.c: fix a memory leak in index_commonancestorsheads
Augie Fackler <augie@google.com>
parents:
23944
diff
changeset
|
1606 Py_DECREF(obj); |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1607 goto bail; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1608 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1609 val = PyInt_AsLong(obj); |
23945
33d6aaf84c9e
parsers.c: fix a memory leak in index_commonancestorsheads
Augie Fackler <augie@google.com>
parents:
23944
diff
changeset
|
1610 Py_DECREF(obj); |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1611 if (val == -1) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1612 ret = PyList_New(0); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1613 goto done; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1614 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1615 if (val < 0 || val >= len) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1616 PyErr_SetString(PyExc_IndexError, |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1617 "index out of range"); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1618 goto bail; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1619 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1620 /* this cheesy bloom filter lets us avoid some more |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1621 * expensive duplicate checks in the common set-is-disjoint |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1622 * case */ |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1623 x = 1ull << (val & 0x3f); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1624 if (repeat & x) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1625 int k; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1626 for (k = 0; k < revcount; k++) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1627 if (val == revs[k]) |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1628 goto duplicate; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1629 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1630 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1631 else repeat |= x; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1632 if (revcount >= capacity) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1633 PyErr_Format(PyExc_OverflowError, |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1634 "bitset size (%d) > capacity (%d)", |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1635 revcount, capacity); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1636 goto bail; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1637 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1638 revs[revcount++] = (int)val; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1639 duplicate:; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1640 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1641 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1642 if (revcount == 0) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1643 ret = PyList_New(0); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1644 goto done; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1645 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1646 if (revcount == 1) { |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1647 PyObject *obj; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1648 ret = PyList_New(1); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1649 if (ret == NULL) |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1650 goto bail; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1651 obj = PyInt_FromLong(revs[0]); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1652 if (obj == NULL) |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1653 goto bail; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1654 PyList_SET_ITEM(ret, 0, obj); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1655 goto done; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1656 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1657 |
21103
628c16489d1c
parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
21102
diff
changeset
|
1658 ret = find_gca_candidates(self, revs, revcount); |
628c16489d1c
parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
21102
diff
changeset
|
1659 if (ret == NULL) |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1660 goto bail; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1661 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1662 done: |
31469
a43fd9ec2a39
parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31426
diff
changeset
|
1663 PyMem_Free(revs); |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1664 return ret; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1665 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1666 bail: |
31469
a43fd9ec2a39
parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31426
diff
changeset
|
1667 PyMem_Free(revs); |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1668 Py_XDECREF(ret); |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1669 return NULL; |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1670 } |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1671 |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1672 /* |
24004
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1673 * Given a (possibly overlapping) set of revs, return the greatest |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1674 * common ancestors: those with the longest path to the root. |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1675 */ |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1676 static PyObject *index_ancestors(indexObject *self, PyObject *args) |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1677 { |
26048
0be2f81aadc3
parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents:
26044
diff
changeset
|
1678 PyObject *ret; |
24004
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1679 PyObject *gca = index_commonancestorsheads(self, args); |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1680 if (gca == NULL) |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1681 return NULL; |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1682 |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1683 if (PyList_GET_SIZE(gca) <= 1) { |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1684 return gca; |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1685 } |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1686 |
26048
0be2f81aadc3
parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents:
26044
diff
changeset
|
1687 ret = find_deepest(self, gca); |
0be2f81aadc3
parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents:
26044
diff
changeset
|
1688 Py_DECREF(gca); |
0be2f81aadc3
parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents:
26044
diff
changeset
|
1689 return ret; |
24004
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1690 } |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1691 |
8a5267cd5286
parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents:
23948
diff
changeset
|
1692 /* |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1693 * 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
|
1694 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1695 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
|
1696 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1697 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
|
1698 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1699 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
|
1700 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
|
1701 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
|
1702 |
30100
c5afe5531709
parsers: convert PyString* to PyBytes*
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30090
diff
changeset
|
1703 nt_insert(self, PyBytes_AS_STRING(node), -1); |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1704 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1705 |
16732
277e2acb7e5c
parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents:
16699
diff
changeset
|
1706 if (start == 0) |
277e2acb7e5c
parsers: use Py_CLEAR where appropriate
Bryan O'Sullivan <bryano@fb.com>
parents:
16699
diff
changeset
|
1707 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
|
1708 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1709 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1710 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1711 * 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
|
1712 * 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
|
1713 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1714 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
|
1715 { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1716 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
|
1717 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
|
1718 int ret = 0; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1719 |
30171
7a3b59f0329a
parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30169
diff
changeset
|
1720 /* Argument changed from PySliceObject* to PyObject* in Python 3. */ |
7a3b59f0329a
parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30169
diff
changeset
|
1721 #ifdef IS_PY3K |
7a3b59f0329a
parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30169
diff
changeset
|
1722 if (PySlice_GetIndicesEx(item, length, |
7a3b59f0329a
parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30169
diff
changeset
|
1723 #else |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1724 if (PySlice_GetIndicesEx((PySliceObject*)item, length, |
30171
7a3b59f0329a
parsers: avoid PySliceObject cast on Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
30169
diff
changeset
|
1725 #endif |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1726 &start, &stop, &step, &slicelength) < 0) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1727 return -1; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1728 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1729 if (slicelength <= 0) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1730 return 0; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1731 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1732 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
|
1733 stop = start; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
1734 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1735 if (step < 0) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1736 stop = start + 1; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1737 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
|
1738 step = -step; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1739 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1740 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1741 if (step != 1) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1742 PyErr_SetString(PyExc_ValueError, |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1743 "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
|
1744 return -1; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
1745 } |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1746 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1747 if (stop != length - 1) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1748 PyErr_SetString(PyExc_IndexError, |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1749 "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
|
1750 return -1; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1751 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1752 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1753 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
|
1754 if (self->nt) { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1755 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
|
1756 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1757 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
|
1758 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
|
1759 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1760 if (node) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1761 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
|
1762 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1763 if (self->added) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1764 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
|
1765 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
|
1766 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
|
1767 } |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1768 self->length = start + 1; |
18504
d1d5fdcc2d46
parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents:
18430
diff
changeset
|
1769 if (start < self->raw_length) { |
d1d5fdcc2d46
parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents:
18430
diff
changeset
|
1770 if (self->cache) { |
d1d5fdcc2d46
parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents:
18430
diff
changeset
|
1771 Py_ssize_t i; |
d1d5fdcc2d46
parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents:
18430
diff
changeset
|
1772 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
|
1773 Py_CLEAR(self->cache[i]); |
d1d5fdcc2d46
parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents:
18430
diff
changeset
|
1774 } |
16784
12a852c7c763
parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents:
16732
diff
changeset
|
1775 self->raw_length = start; |
18504
d1d5fdcc2d46
parsers: fix memleak of revlog cache entries on strip
Yuya Nishihara <yuya@tcha.org>
parents:
18430
diff
changeset
|
1776 } |
16784
12a852c7c763
parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents:
16732
diff
changeset
|
1777 goto done; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
1778 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
1779 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1780 if (self->nt) { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1781 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
|
1782 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
|
1783 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
|
1784 } |
16784
12a852c7c763
parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents:
16732
diff
changeset
|
1785 if (self->added) |
12a852c7c763
parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents:
16732
diff
changeset
|
1786 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
|
1787 PyList_GET_SIZE(self->added), NULL); |
12a852c7c763
parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents:
16732
diff
changeset
|
1788 done: |
16787
bda96ce993f9
parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents:
16786
diff
changeset
|
1789 Py_CLEAR(self->headrevs); |
16784
12a852c7c763
parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents:
16732
diff
changeset
|
1790 return ret; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1791 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1792 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1793 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1794 * Supported ops: |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1795 * |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1796 * slice deletion |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1797 * 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
|
1798 * 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
|
1799 */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1800 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
|
1801 PyObject *value) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1802 { |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1803 char *node; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1804 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
|
1805 long rev; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1806 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1807 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
|
1808 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
|
1809 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1810 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
|
1811 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1812 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1813 if (value == NULL) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1814 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
|
1815 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
|
1816 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
|
1817 if (!PyErr_Occurred()) |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1818 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
|
1819 return -1; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1820 } |
23468
ee311681e591
parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents:
23087
diff
changeset
|
1821 |
ee311681e591
parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents:
23087
diff
changeset
|
1822 if (nt_init(self) == -1) |
ee311681e591
parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents:
23087
diff
changeset
|
1823 return -1; |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1824 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
|
1825 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1826 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1827 /* |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1828 * 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
|
1829 * 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
|
1830 */ |
22401
9ba8a93e55f5
parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents:
22400
diff
changeset
|
1831 static Py_ssize_t inline_scan(indexObject *self, const char **offsets) |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1832 { |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1833 const char *data = (const char *)self->buf.buf; |
20167
09e41ac6289d
mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents:
20109
diff
changeset
|
1834 Py_ssize_t pos = 0; |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1835 Py_ssize_t end = self->buf.len; |
16863
bbedef66c6f3
parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents:
16787
diff
changeset
|
1836 long incr = v1_hdrsize; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1837 Py_ssize_t len = 0; |
13254
5ef5eb1f3515
revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents:
11361
diff
changeset
|
1838 |
20167
09e41ac6289d
mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents:
20109
diff
changeset
|
1839 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
|
1840 uint32_t comp_len; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1841 /* 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
|
1842 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
|
1843 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
|
1844 if (offsets) |
20167
09e41ac6289d
mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents:
20109
diff
changeset
|
1845 offsets[len] = data + pos; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1846 len++; |
20167
09e41ac6289d
mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents:
20109
diff
changeset
|
1847 pos += incr; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1848 } |
13254
5ef5eb1f3515
revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents:
11361
diff
changeset
|
1849 |
20167
09e41ac6289d
mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents:
20109
diff
changeset
|
1850 if (pos != end) { |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1851 if (!PyErr_Occurred()) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1852 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
|
1853 return -1; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1854 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1855 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1856 return len; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1857 } |
13254
5ef5eb1f3515
revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents:
11361
diff
changeset
|
1858 |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1859 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
|
1860 { |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1861 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
|
1862 Py_ssize_t size; |
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1863 |
20109
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1864 /* 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
|
1865 self->raw_length = 0; |
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1866 self->added = NULL; |
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1867 self->cache = NULL; |
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1868 self->data = NULL; |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1869 memset(&self->buf, 0, sizeof(self->buf)); |
20109
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1870 self->headrevs = NULL; |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
1871 self->filteredrevs = Py_None; |
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
1872 Py_INCREF(Py_None); |
20109
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1873 self->nt = NULL; |
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1874 self->offsets = NULL; |
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1875 |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1876 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
|
1877 return -1; |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1878 if (!PyObject_CheckBuffer(data_obj)) { |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1879 PyErr_SetString(PyExc_TypeError, |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1880 "data does not support buffer interface"); |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1881 return -1; |
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1882 } |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1883 |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1884 if (PyObject_GetBuffer(data_obj, &self->buf, PyBUF_SIMPLE) == -1) |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1885 return -1; |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1886 size = self->buf.len; |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1887 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1888 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
|
1889 self->data = data_obj; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1890 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1891 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
|
1892 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
|
1893 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
|
1894 self->ntrev = -1; |
16597
b767382a8675
parsers: fix refcount bug on corrupt index
Matt Mackall <mpm@selenic.com>
parents:
16572
diff
changeset
|
1895 Py_INCREF(self->data); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
1896 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1897 if (self->inlined) { |
22401
9ba8a93e55f5
parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents:
22400
diff
changeset
|
1898 Py_ssize_t len = inline_scan(self, NULL); |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1899 if (len == -1) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1900 goto bail; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1901 self->raw_length = len; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1902 self->length = len + 1; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1903 } else { |
16863
bbedef66c6f3
parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents:
16787
diff
changeset
|
1904 if (size % v1_hdrsize) { |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1905 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
|
1906 goto bail; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1907 } |
16863
bbedef66c6f3
parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents:
16787
diff
changeset
|
1908 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
|
1909 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
|
1910 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1911 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1912 return 0; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1913 bail: |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1914 return -1; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1915 } |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1916 |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1917 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
|
1918 { |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
1919 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
|
1920 return (PyObject *)self; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1921 } |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1922 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1923 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
|
1924 { |
16370
28bb4daf070c
parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents:
16363
diff
changeset
|
1925 _index_clearcaches(self); |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
1926 Py_XDECREF(self->filteredrevs); |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1927 if (self->buf.buf) { |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1928 PyBuffer_Release(&self->buf); |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1929 memset(&self->buf, 0, sizeof(self->buf)); |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
1930 } |
20109
e57c532c3835
parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents:
19728
diff
changeset
|
1931 Py_XDECREF(self->data); |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1932 Py_XDECREF(self->added); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1933 PyObject_Del(self); |
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 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1936 static PySequenceMethods index_sequence_methods = { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1937 (lenfunc)index_length, /* sq_length */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1938 0, /* sq_concat */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1939 0, /* sq_repeat */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1940 (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
|
1941 0, /* sq_slice */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1942 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
|
1943 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
|
1944 (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
|
1945 }; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1946 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1947 static PyMappingMethods index_mapping_methods = { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1948 (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
|
1949 (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
|
1950 (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
|
1951 }; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1952 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1953 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
|
1954 {"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
|
1955 "return the gca set of the given revs"}, |
21102
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1956 {"commonancestorsheads", (PyCFunction)index_commonancestorsheads, |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1957 METH_VARARGS, |
4eb6553789e1
parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents:
20797
diff
changeset
|
1958 "return the heads of the common ancestors 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
|
1959 {"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
|
1960 "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
|
1961 {"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
|
1962 "get an index entry"}, |
25190
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
1963 {"computephasesmapsets", (PyCFunction)compute_phases_map_sets, |
22438cfd11b5
phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents:
24879
diff
changeset
|
1964 METH_VARARGS, "compute phases"}, |
26053
b68c9d232db6
reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents:
26052
diff
changeset
|
1965 {"reachableroots2", (PyCFunction)reachableroots2, METH_VARARGS, |
26004
ff89383a97db
reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents:
25911
diff
changeset
|
1966 "reachableroots"}, |
22484
2b5940f64750
obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents:
22403
diff
changeset
|
1967 {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS, |
23087
42342f9afe01
parsers: introduce headrevsfiltered in C extension
Mads Kiilerich <madski@unity3d.com>
parents:
23073
diff
changeset
|
1968 "get head revisions"}, /* Can do filtering since 3.2 */ |
42342f9afe01
parsers: introduce headrevsfiltered in C extension
Mads Kiilerich <madski@unity3d.com>
parents:
23073
diff
changeset
|
1969 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS, |
42342f9afe01
parsers: introduce headrevsfiltered in C extension
Mads Kiilerich <madski@unity3d.com>
parents:
23073
diff
changeset
|
1970 "get filtered head revisions"}, /* Can always do filtering */ |
33171
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
1971 {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS, |
6d678ab1b10d
revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32384
diff
changeset
|
1972 "determine revisions with deltas to reconstruct fulltext"}, |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1973 {"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
|
1974 "insert an index entry"}, |
16665
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1975 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS, |
e410be860393
revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents:
16664
diff
changeset
|
1976 "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
|
1977 {"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
|
1978 "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
|
1979 {NULL} /* Sentinel */ |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1980 }; |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1981 |
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
1982 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
|
1983 {"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
|
1984 {NULL} /* Sentinel */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1985 }; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1986 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1987 static PyTypeObject indexType = { |
34861
6ece4a85c350
cext: add /* header */ comment to all PyVarObject_HEAD_INIT() calls
Augie Fackler <augie@google.com>
parents:
34440
diff
changeset
|
1988 PyVarObject_HEAD_INIT(NULL, 0) /* header */ |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1989 "parsers.index", /* tp_name */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1990 sizeof(indexObject), /* tp_basicsize */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1991 0, /* tp_itemsize */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1992 (destructor)index_dealloc, /* tp_dealloc */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1993 0, /* tp_print */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1994 0, /* tp_getattr */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1995 0, /* tp_setattr */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1996 0, /* tp_compare */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1997 0, /* tp_repr */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1998 0, /* tp_as_number */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
1999 &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
|
2000 &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
|
2001 0, /* tp_hash */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2002 0, /* tp_call */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2003 0, /* tp_str */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2004 0, /* tp_getattro */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2005 0, /* tp_setattro */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2006 0, /* tp_as_buffer */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2007 Py_TPFLAGS_DEFAULT, /* tp_flags */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2008 "revlog index", /* tp_doc */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2009 0, /* tp_traverse */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2010 0, /* tp_clear */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2011 0, /* tp_richcompare */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2012 0, /* tp_weaklistoffset */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2013 0, /* tp_iter */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2014 0, /* tp_iternext */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2015 index_methods, /* tp_methods */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2016 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
|
2017 index_getset, /* tp_getset */ |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2018 0, /* tp_base */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2019 0, /* tp_dict */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2020 0, /* tp_descr_get */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2021 0, /* tp_descr_set */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2022 0, /* tp_dictoffset */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2023 (initproc)index_init, /* tp_init */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2024 0, /* tp_alloc */ |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2025 }; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2026 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2027 /* |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
2028 * 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
|
2029 * follows: |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2030 * |
16414
e8d37b78acfb
parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents:
16393
diff
changeset
|
2031 * index: an index object that lazily parses RevlogNG records |
30577
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
2032 * cache: if data is inlined, a tuple (0, index_file_content), else None |
6146d5acee69
parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents:
30171
diff
changeset
|
2033 * index_file_content could be a string, or a buffer |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2034 * |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2035 * added complications are for backwards compatibility |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2036 */ |
32378
7d0c69505a66
cext: extract revlog/index parsing code to own C file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32372
diff
changeset
|
2037 PyObject *parse_index2(PyObject *self, PyObject *args) |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2038 { |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
2039 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
|
2040 indexObject *idx; |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
2041 int ret; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2042 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2043 idx = PyObject_New(indexObject, &indexType); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2044 if (idx == NULL) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2045 goto bail; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2046 |
16572
8d44b5a2974f
parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents:
16437
diff
changeset
|
2047 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
|
2048 if (ret == -1) |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2049 goto bail; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2050 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2051 if (idx->inlined) { |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2052 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
|
2053 if (cache == NULL) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2054 goto bail; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2055 } else { |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2056 cache = Py_None; |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2057 Py_INCREF(cache); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2058 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2059 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2060 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
|
2061 if (!tuple) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2062 goto bail; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2063 return tuple; |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2064 |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2065 bail: |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2066 Py_XDECREF(idx); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2067 Py_XDECREF(cache); |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2068 Py_XDECREF(tuple); |
7108
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2069 return NULL; |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2070 } |
1ca878d7b849
C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents:
7093
diff
changeset
|
2071 |
32378
7d0c69505a66
cext: extract revlog/index parsing code to own C file
Gregory Szorc <gregory.szorc@gmail.com>
parents:
32372
diff
changeset
|
2072 void revlog_module_init(PyObject *mod) |
24017
72c9b5ae7278
parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents:
24004
diff
changeset
|
2073 { |
16604
48e42f984074
parsers: statically initializing tp_new to PyType_GenericNew is not portable
Adrian Buehlmann <adrian@cadifra.com>
parents:
16597
diff
changeset
|
2074 indexType.tp_new = PyType_GenericNew; |
32384
2e5a476b2e46
cext: move back finalization of dirstateTupleType where it should be
Yuya Nishihara <yuya@tcha.org>
parents:
32378
diff
changeset
|
2075 if (PyType_Ready(&indexType) < 0) |
16363
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2076 return; |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2077 Py_INCREF(&indexType); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2078 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
|
2079 |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2080 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
|
2081 -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
|
2082 if (nullentry) |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2083 PyObject_GC_UnTrack(nullentry); |
2cdd7e63211b
parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents:
15033
diff
changeset
|
2084 } |