annotate mercurial/cext/revlog.c @ 39111:acd23830bcd6

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