annotate mercurial/cext/revlog.c @ 48923:428177ad70b0

help: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12328
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 21 Feb 2022 11:10:08 -0700
parents e633e660158f
children 4bb04a506af6
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
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46717
diff changeset
4 Copyright 2008 Olivia Mackall <olivia@selenic.com> and others
6389
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
42067
b01bbb8ff1f2 cext: make revlog.c PY_SSIZE_T_CLEAN
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41283
diff changeset
10 #define PY_SSIZE_T_CLEAN
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 #include <Python.h>
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
12 #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
13 #include <ctype.h>
40704
7da3729d4b45 sparse-revlog: add a `index_get_length` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40703
diff changeset
14 #include <limits.h>
17356
511dfb34b412 parsers: fix an integer size warning issued by clang
Bryan O'Sullivan <bryano@fb.com>
parents: 17353
diff changeset
15 #include <stddef.h>
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
16 #include <stdlib.h>
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
17 #include <string.h>
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
18 #include <structmember.h>
6389
0231f763ebc8 manifest: improve parsing performance by 8x via a new C extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
34438
b90e8da190da cext: reorder #include
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34437
diff changeset
20 #include "bitmanipulation.h"
33758
0f4ac3b6dee4 cext: factor out header for charencode.c
Yuya Nishihara <yuya@tcha.org>
parents: 33475
diff changeset
21 #include "charencode.h"
46328
0216abfb2d3e clang-format: reorder includes to appease the formatter
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46317
diff changeset
22 #include "compat.h"
40859
aa76be85029b revlog: export symbol of indexType
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
23 #include "revlog.h"
11361
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
24 #include "util.h"
3de3d670d2b6 parsers.c: Added support for py3k.
Renato Cunha <renatoc@gmail.com>
parents: 10449
diff changeset
25
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
26 typedef struct indexObjectStruct indexObject;
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
27
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
28 typedef struct {
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
29 int children[16];
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
30 } nodetreenode;
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
31
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
32 typedef struct {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
33 int abi_version;
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44486
diff changeset
34 Py_ssize_t (*index_length)(const indexObject *);
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44486
diff changeset
35 const char *(*index_node)(indexObject *, Py_ssize_t);
48852
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
36 int (*fast_rank)(indexObject *, Py_ssize_t);
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
37 int (*index_parents)(PyObject *, int, int *);
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
38 } Revlog_CAPI;
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
39
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
40 /*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
41 * 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
42 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
43 * Positive value is index of the next node in the trie
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
44 * 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
45 * Zero is empty
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
46 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
47 typedef struct {
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
48 indexObject *index;
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
49 nodetreenode *nodes;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
50 Py_ssize_t nodelen;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
51 size_t length; /* # nodes in use */
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
52 size_t capacity; /* # nodes allocated */
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
53 int depth; /* maximum depth of tree */
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
54 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
55 } nodetree;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
56
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
57 typedef struct {
40560
8c1f36bf2d3e revlog: add a comment to help clang-format produce less-awful results
Augie Fackler <augie@google.com>
parents: 40460
diff changeset
58 PyObject_HEAD /* ; */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
59 nodetree nt;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
60 } nodetreeObject;
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
61
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
62 /*
26098
ce26928cbe41 spelling: behaviour -> behavior
timeless@mozdev.org
parents: 26080
diff changeset
63 * 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
64 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
65 * When used in a list-like way (with integer keys), we decode an
43582
ae5e39512ca0 revlog: delete references to deleted nullid sentinel value
Martin von Zweigbergk <martinvonz@google.com>
parents: 43554
diff changeset
66 * entry in a RevlogNG index file on demand. We have limited support for
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
67 * integer-keyed insert and delete, only at elements right before the
43582
ae5e39512ca0 revlog: delete references to deleted nullid sentinel value
Martin von Zweigbergk <martinvonz@google.com>
parents: 43554
diff changeset
68 * end.
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
69 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
70 * 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
71 * 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
72 */
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
73 struct indexObjectStruct {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
74 PyObject_HEAD
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
75 /* Type-specific fields go here. */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
76 PyObject *data; /* raw bytes of index */
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
77 Py_ssize_t nodelen; /* digest size of the hash, 20 for SHA-1 */
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
78 PyObject *nullentry; /* fast path for references to null */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
79 Py_buffer buf; /* buffer of data */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
80 const char **offsets; /* populated on demand */
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
81 Py_ssize_t length; /* current on-disk number of elements */
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
82 unsigned new_length; /* number of added elements */
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
83 unsigned added_length; /* space reserved for added elements */
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
84 char *added; /* populated on demand */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
85 PyObject *headrevs; /* cache, invalidated on changes */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
86 PyObject *filteredrevs; /* filtered revs set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
87 nodetree nt; /* base-16 trie */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
88 int ntinitialized; /* 0 or 1 */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
89 int ntrev; /* last rev scanned */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
90 int ntlookups; /* # lookups */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
91 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
92 int inlined;
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
93 long entry_size; /* size of index headers. Differs in v1 v.s. v2 format
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
94 */
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47259
diff changeset
95 long rust_ext_compat; /* compatibility with being used in rust
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47259
diff changeset
96 extensions */
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
97 long format_version; /* format version selector (format_*) */
38939
53bc73fae1a3 index: add pointer from nodetree back to index
Martin von Zweigbergk <martinvonz@google.com>
parents: 38938
diff changeset
98 };
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
99
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
100 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
101 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
102 return self->length + self->new_length;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
103 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
104
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
105 static const char nullid[32] = {0};
40960
43974cd44967 revlog: introduce a constant for nullrev in `revlog.c`
Boris Feld <boris.feld@octobus.net>
parents: 40862
diff changeset
106 static const Py_ssize_t nullrev = -1;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
107
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
108 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
109
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
110 static int index_find_node(indexObject *self, const char *node);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
111
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
112 #if LONG_MAX == 0x7fffffffL
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
113 static const char *const tuple_format = "Kiiiiiiy#KiBBi";
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
114 #else
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
115 static const char *const tuple_format = "kiiiiiiy#kiBBi";
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
116 #endif
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
117
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
118 /* A RevlogNG v1 index entry is 64 bytes long. */
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
119 static const long v1_entry_size = 64;
16863
bbedef66c6f3 parsers: replace magic number 64 with symbolic constant
Bryan O'Sullivan <bryano@fb.com>
parents: 16787
diff changeset
120
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
121 /* A Revlogv2 index entry is 96 bytes long. */
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
122 static const long v2_entry_size = 96;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
123
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
124 /* A Changelogv2 index entry is 96 bytes long. */
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
125 static const long cl2_entry_size = 96;
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
126
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
127 /* Internal format version.
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
128 * Must match their counterparts in revlogutils/constants.py */
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
129 static const long format_v1 = 1; /* constants.py: REVLOGV1 */
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
130 static const long format_v2 = 0xDEAD; /* constants.py: REVLOGV2 */
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
131 static const long format_cl2 = 0xD34D; /* constants.py: CHANGELOGV2 */
47141
ac72eee94035 revlog: introduce an explicit `format_version` member in the index struct
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47140
diff changeset
132
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
133 static const long entry_v1_offset_high = 0;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
134 static const long entry_v1_offset_offset_flags = 4;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
135 static const long entry_v1_offset_comp_len = 8;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
136 static const long entry_v1_offset_uncomp_len = 12;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
137 static const long entry_v1_offset_base_rev = 16;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
138 static const long entry_v1_offset_link_rev = 20;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
139 static const long entry_v1_offset_parent_1 = 24;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
140 static const long entry_v1_offset_parent_2 = 28;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
141 static const long entry_v1_offset_node_id = 32;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
142
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
143 static const long entry_v2_offset_high = 0;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
144 static const long entry_v2_offset_offset_flags = 4;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
145 static const long entry_v2_offset_comp_len = 8;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
146 static const long entry_v2_offset_uncomp_len = 12;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
147 static const long entry_v2_offset_base_rev = 16;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
148 static const long entry_v2_offset_link_rev = 20;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
149 static const long entry_v2_offset_parent_1 = 24;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
150 static const long entry_v2_offset_parent_2 = 28;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
151 static const long entry_v2_offset_node_id = 32;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
152 static const long entry_v2_offset_sidedata_offset = 64;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
153 static const long entry_v2_offset_sidedata_comp_len = 72;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
154 static const long entry_v2_offset_all_comp_mode = 76;
48767
654baf1faa52 revlog: memset whole record instead of dealing with padding
pacien <pacien.trangirard@pacien.net>
parents: 48766
diff changeset
155 /* next free offset: 77 */
48721
a9364de9be29 revlog: extract entry byte offsets into named constants
pacien <pacien.trangirard@pacien.net>
parents: 48499
diff changeset
156
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
157 static const long entry_cl2_offset_high = 0;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
158 static const long entry_cl2_offset_offset_flags = 4;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
159 static const long entry_cl2_offset_comp_len = 8;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
160 static const long entry_cl2_offset_uncomp_len = 12;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
161 static const long entry_cl2_offset_parent_1 = 16;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
162 static const long entry_cl2_offset_parent_2 = 20;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
163 static const long entry_cl2_offset_node_id = 24;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
164 static const long entry_cl2_offset_sidedata_offset = 56;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
165 static const long entry_cl2_offset_sidedata_comp_len = 64;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
166 static const long entry_cl2_offset_all_comp_mode = 68;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
167 static const long entry_cl2_offset_rank = 69;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
168 /* next free offset: 73 */
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
169
47249
130c9f7ed914 revlog: add a "data compression mode" entry in the index tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47235
diff changeset
170 static const char comp_mode_inline = 2;
48499
52034c42c09d rank: add a "rank" value to the revlog-entry tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47863
diff changeset
171 static const char rank_unknown = -1;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
172
39219
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
173 static void raise_revlog_error(void)
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
174 {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
175 PyObject *mod = NULL, *dict = NULL, *errclass = NULL;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
176
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
177 mod = PyImport_ImportModule("mercurial.error");
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
178 if (mod == NULL) {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
179 goto cleanup;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
180 }
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
181
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
182 dict = PyModule_GetDict(mod);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
183 if (dict == NULL) {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
184 goto cleanup;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
185 }
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
186 Py_INCREF(dict);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
187
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
188 errclass = PyDict_GetItemString(dict, "RevlogError");
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
189 if (errclass == NULL) {
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
190 PyErr_SetString(PyExc_SystemError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
191 "could not find RevlogError");
39219
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
192 goto cleanup;
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
193 }
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
194
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
195 /* value of exception is ignored by callers */
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
196 PyErr_SetString(errclass, "RevlogError");
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
197
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
198 cleanup:
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
199 Py_XDECREF(dict);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
200 Py_XDECREF(mod);
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
201 }
f85b25608252 index: move raise_revlog_error() further up
Martin von Zweigbergk <martinvonz@google.com>
parents: 39218
diff changeset
202
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
203 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
204 * 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
205 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
206 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
207 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
208 if (pos >= self->length)
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
209 return self->added + (pos - self->length) * self->entry_size;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
210
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
211 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
212 if (self->offsets == NULL) {
44580
3122058df7a5 cext: move variable declaration to the top of the block for C89 support
Matt Harbison <matt_harbison@yahoo.com>
parents: 44500
diff changeset
213 Py_ssize_t ret;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
214 self->offsets =
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
215 PyMem_Malloc(self->length * 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
216 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
217 return (const char *)PyErr_NoMemory();
44580
3122058df7a5 cext: move variable declaration to the top of the block for C89 support
Matt Harbison <matt_harbison@yahoo.com>
parents: 44500
diff changeset
218 ret = inline_scan(self, self->offsets);
44500
864e9534d3d4 cext-index: propagate inline_scan error in `index_deref`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44066
diff changeset
219 if (ret == -1) {
864e9534d3d4 cext-index: propagate inline_scan error in `index_deref`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44066
diff changeset
220 return NULL;
864e9534d3d4 cext-index: propagate inline_scan error in `index_deref`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44066
diff changeset
221 };
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
222 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
223 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
224 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
225
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
226 return (const char *)(self->buf.buf) + pos * self->entry_size;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
227 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
228
40812
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
229 /*
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
230 * Get parents of the given rev.
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
231 *
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
232 * The specified rev must be valid and must not be nullrev. A returned
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
233 * parent revision may be nullrev, but is guaranteed to be in valid range.
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
234 */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
235 static inline int index_get_parents(indexObject *self, Py_ssize_t rev, int *ps,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
236 int maxrev)
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
237 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
238 const char *data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
239
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
240 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
241 ps[0] = getbe32(data + entry_v1_offset_parent_1);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
242 ps[1] = getbe32(data + entry_v1_offset_parent_2);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
243 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
244 ps[0] = getbe32(data + entry_v2_offset_parent_1);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
245 ps[1] = getbe32(data + entry_v2_offset_parent_2);
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
246 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
247 ps[0] = getbe32(data + entry_cl2_offset_parent_1);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
248 ps[1] = getbe32(data + entry_cl2_offset_parent_2);
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
249 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
250 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
251 return -1;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
252 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
253
25810
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
254 /* 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
255 * there is a risk of buffer overflow to trust them unconditionally. */
40812
9cdd525d97b2 revlog: fix out-of-bounds access by negative parents read from revlog (SEC)
Yuya Nishihara <yuya@tcha.org>
parents: 40454
diff changeset
256 if (ps[0] < -1 || ps[0] > maxrev || ps[1] < -1 || ps[1] > maxrev) {
25810
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
257 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
258 return -1;
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
259 }
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
260 return 0;
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
261 }
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
262
40861
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
263 /*
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
264 * Get parents of the given rev.
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
265 *
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
266 * If the specified rev is out of range, IndexError will be raised. If the
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
267 * revlog entry is corrupted, ValueError may be raised.
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
268 *
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
269 * Returns 0 on success or -1 on failure.
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
270 */
44467
9db11679f8ac cext: make HgRevlogIndex_GetParents private again
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44066
diff changeset
271 static int HgRevlogIndex_GetParents(PyObject *op, int rev, int *ps)
40861
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
272 {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
273 int tiprev;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
274 if (!op || !HgRevlogIndex_Check(op) || !ps) {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
275 PyErr_BadInternalCall();
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
276 return -1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
277 }
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
278 tiprev = (int)index_length((indexObject *)op) - 1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
279 if (rev < -1 || rev > tiprev) {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
280 PyErr_Format(PyExc_IndexError, "rev out of range: %d", rev);
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
281 return -1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
282 } else if (rev == -1) {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
283 ps[0] = ps[1] = -1;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
284 return 0;
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
285 } else {
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
286 return index_get_parents((indexObject *)op, rev, ps, tiprev);
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
287 }
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
288 }
b12700dd261f revlog: add public CPython function to get parent revisions
Yuya Nishihara <yuya@tcha.org>
parents: 40860
diff changeset
289
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
290 static inline int64_t index_get_start(indexObject *self, Py_ssize_t rev)
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
291 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
292 const char *data;
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
293 uint64_t offset;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
294
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
295 if (rev == nullrev)
40961
b54727f82511 sparse-revlog: handle nullrev in index_get_start
Boris Feld <boris.feld@octobus.net>
parents: 40960
diff changeset
296 return 0;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
297
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
298 data = index_deref(self, rev);
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
299
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
300 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
301 offset = getbe32(data + entry_v1_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
302 if (rev == 0) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
303 /* mask out version number for the first entry */
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
304 offset &= 0xFFFF;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
305 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
306 uint32_t offset_high =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
307 getbe32(data + entry_v1_offset_high);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
308 offset |= ((uint64_t)offset_high) << 32;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
309 }
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
310 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
311 offset = getbe32(data + entry_v2_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
312 if (rev == 0) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
313 /* mask out version number for the first entry */
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
314 offset &= 0xFFFF;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
315 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
316 uint32_t offset_high =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
317 getbe32(data + entry_v2_offset_high);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
318 offset |= ((uint64_t)offset_high) << 32;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
319 }
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
320 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
321 uint32_t offset_high = getbe32(data + entry_cl2_offset_high);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
322 offset = getbe32(data + entry_cl2_offset_offset_flags);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
323 offset |= ((uint64_t)offset_high) << 32;
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
324 } else {
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
325 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
326 return -1;
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
327 }
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
328
40703
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
329 return (int64_t)(offset >> 16);
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
330 }
d5b300ec2e89 sparse-revlog: add a `index_get_start` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40598
diff changeset
331
40704
7da3729d4b45 sparse-revlog: add a `index_get_length` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40703
diff changeset
332 static inline int index_get_length(indexObject *self, Py_ssize_t rev)
7da3729d4b45 sparse-revlog: add a `index_get_length` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40703
diff changeset
333 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
334 const char *data;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
335 int tmp;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
336
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
337 if (rev == nullrev)
40962
c6939b353ebd sparse-revlog: handle nullrev in index_get_length
Boris Feld <boris.feld@octobus.net>
parents: 40961
diff changeset
338 return 0;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
339
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
340 data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
341
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
342 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
343 tmp = (int)getbe32(data + entry_v1_offset_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
344 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
345 tmp = (int)getbe32(data + entry_v2_offset_comp_len);
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
346 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
347 tmp = (int)getbe32(data + entry_cl2_offset_comp_len);
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
348 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
349 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
350 return -1;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
351 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
352 if (tmp < 0) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
353 PyErr_Format(PyExc_OverflowError,
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
354 "revlog entry size out of bound (%d)", tmp);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
355 return -1;
40962
c6939b353ebd sparse-revlog: handle nullrev in index_get_length
Boris Feld <boris.feld@octobus.net>
parents: 40961
diff changeset
356 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
357 return tmp;
40704
7da3729d4b45 sparse-revlog: add a `index_get_length` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40703
diff changeset
358 }
25311
d2e88f960d1a parsers: move index_get_parents's declaration higher
Laurent Charignon <lcharignon@fb.com>
parents: 25297
diff changeset
359
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
360 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
361 * 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
362 * 6 bytes: offset
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
363 * 2 bytes: flags
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
364 * 4 bytes: compressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
365 * 4 bytes: uncompressed length
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
366 * 4 bytes: base revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
367 * 4 bytes: link revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
368 * 4 bytes: parent 1 revision
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
369 * 4 bytes: parent 2 revision
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
370 * 32 bytes: nodeid (only 20 bytes used with SHA-1)
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
371 */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
372 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
373 {
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
374 uint64_t offset_flags, sidedata_offset;
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
375 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2,
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
376 sidedata_comp_len, rank = rank_unknown;
47256
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
377 char data_comp_mode, sidedata_comp_mode;
7154
7fdf7a0a41b7 index parser: fix refcounting in case of errors, refactor
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7135
diff changeset
378 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
379 const char *data;
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
380 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
381
40960
43974cd44967 revlog: introduce a constant for nullrev in `revlog.c`
Boris Feld <boris.feld@octobus.net>
parents: 40862
diff changeset
382 if (pos == nullrev) {
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
383 Py_INCREF(self->nullentry);
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
384 return self->nullentry;
38847
f3d394ea17db index: handle index[-1] as nullid more explicitly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38846
diff changeset
385 }
f3d394ea17db index: handle index[-1] as nullid more explicitly
Martin von Zweigbergk <martinvonz@google.com>
parents: 38846
diff changeset
386
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
387 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
388 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
389 return NULL;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
390 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
391
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
392 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
393 if (data == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
394 return NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
395
47250
4dca422d3907 revlog: use `format_version` to dispatch different version in index_get
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47249
diff changeset
396 if (self->format_version == format_v1) {
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
397 offset_flags = getbe32(data + entry_v1_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
398 /*
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
399 * The first entry on-disk needs the version number masked out,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
400 * but this doesn't apply if entries are added to an empty
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
401 * index.
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
402 */
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
403 if (self->length && pos == 0)
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
404 offset_flags &= 0xFFFF;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
405 else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
406 uint32_t offset_high =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
407 getbe32(data + entry_v1_offset_high);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
408 offset_flags |= ((uint64_t)offset_high) << 32;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
409 }
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
410
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
411 comp_len = getbe32(data + entry_v1_offset_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
412 uncomp_len = getbe32(data + entry_v1_offset_uncomp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
413 base_rev = getbe32(data + entry_v1_offset_base_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
414 link_rev = getbe32(data + entry_v1_offset_link_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
415 parent_1 = getbe32(data + entry_v1_offset_parent_1);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
416 parent_2 = getbe32(data + entry_v1_offset_parent_2);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
417 c_node_id = data + entry_v1_offset_node_id;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
418
47142
4292bed8da7c revlog: make the index always return the same tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47141
diff changeset
419 sidedata_offset = 0;
4292bed8da7c revlog: make the index always return the same tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47141
diff changeset
420 sidedata_comp_len = 0;
47251
6bfa6c2c5f15 revlogv2: preserve the compression mode on disk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47250
diff changeset
421 data_comp_mode = comp_mode_inline;
47256
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
422 sidedata_comp_mode = comp_mode_inline;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
423 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
424 offset_flags = getbe32(data + entry_v2_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
425 /*
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
426 * The first entry on-disk needs the version number masked out,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
427 * but this doesn't apply if entries are added to an empty
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
428 * index.
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
429 */
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
430 if (self->length && pos == 0)
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
431 offset_flags &= 0xFFFF;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
432 else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
433 uint32_t offset_high =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
434 getbe32(data + entry_v2_offset_high);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
435 offset_flags |= ((uint64_t)offset_high) << 32;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
436 }
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
437
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
438 comp_len = getbe32(data + entry_v2_offset_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
439 uncomp_len = getbe32(data + entry_v2_offset_uncomp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
440 base_rev = getbe32(data + entry_v2_offset_base_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
441 link_rev = getbe32(data + entry_v2_offset_link_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
442 parent_1 = getbe32(data + entry_v2_offset_parent_1);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
443 parent_2 = getbe32(data + entry_v2_offset_parent_2);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
444 c_node_id = data + entry_v2_offset_node_id;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
445
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
446 sidedata_offset =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
447 getbe64(data + entry_v2_offset_sidedata_offset);
48721
a9364de9be29 revlog: extract entry byte offsets into named constants
pacien <pacien.trangirard@pacien.net>
parents: 48499
diff changeset
448 sidedata_comp_len =
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
449 getbe32(data + entry_v2_offset_sidedata_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
450 data_comp_mode = data[entry_v2_offset_all_comp_mode] & 3;
48721
a9364de9be29 revlog: extract entry byte offsets into named constants
pacien <pacien.trangirard@pacien.net>
parents: 48499
diff changeset
451 sidedata_comp_mode =
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
452 ((data[entry_v2_offset_all_comp_mode] >> 2) & 3);
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
453 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
454 uint32_t offset_high = getbe32(data + entry_cl2_offset_high);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
455 offset_flags = getbe32(data + entry_cl2_offset_offset_flags);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
456 offset_flags |= ((uint64_t)offset_high) << 32;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
457 comp_len = getbe32(data + entry_cl2_offset_comp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
458 uncomp_len = getbe32(data + entry_cl2_offset_uncomp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
459 /* base_rev and link_rev are not stored in changelogv2, but are
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
460 still used by some functions shared with the other revlogs.
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
461 They are supposed to contain links to other revisions,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
462 but they always point to themselves in the case of a changelog.
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
463 */
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
464 base_rev = pos;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
465 link_rev = pos;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
466 parent_1 = getbe32(data + entry_cl2_offset_parent_1);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
467 parent_2 = getbe32(data + entry_cl2_offset_parent_2);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
468 c_node_id = data + entry_cl2_offset_node_id;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
469 sidedata_offset =
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
470 getbe64(data + entry_cl2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
471 sidedata_comp_len =
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
472 getbe32(data + entry_cl2_offset_sidedata_comp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
473 data_comp_mode = data[entry_cl2_offset_all_comp_mode] & 3;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
474 sidedata_comp_mode =
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
475 ((data[entry_cl2_offset_all_comp_mode] >> 2) & 3);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
476 rank = getbe32(data + entry_cl2_offset_rank);
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
477 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
478 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
479 return NULL;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
480 }
47142
4292bed8da7c revlog: make the index always return the same tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47141
diff changeset
481
47143
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
482 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len,
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
483 base_rev, link_rev, parent_1, parent_2, c_node_id,
47249
130c9f7ed914 revlog: add a "data compression mode" entry in the index tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47235
diff changeset
484 self->nodelen, sidedata_offset, sidedata_comp_len,
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
485 data_comp_mode, sidedata_comp_mode, rank);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
486 }
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
487 /*
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
488 * Pack header information in binary
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
489 */
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
490 static PyObject *index_pack_header(indexObject *self, PyObject *args)
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
491 {
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
492 int header;
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
493 char out[4];
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
494 if (!PyArg_ParseTuple(args, "I", &header)) {
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
495 return NULL;
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
496 }
47235
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
497 if (self->format_version != format_v1) {
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
498 PyErr_Format(PyExc_RuntimeError,
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
499 "version header should go in the docket, not the "
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
500 "index: %lu",
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
501 header);
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
502 return NULL;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
503 }
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
504 putbe32(header, out);
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
505 return PyBytes_FromStringAndSize(out, 4);
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
506 }
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
507 /*
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
508 * Return the raw binary string representing a revision
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
509 */
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
510 static PyObject *index_entry_binary(indexObject *self, PyObject *value)
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
511 {
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
512 long rev;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
513 const char *data;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
514 Py_ssize_t length = index_length(self);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
515
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
516 if (!pylong_to_long(value, &rev)) {
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
517 return NULL;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
518 }
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
519 if (rev < 0 || rev >= length) {
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
520 PyErr_Format(PyExc_ValueError, "revlog index out of range: %ld",
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
521 rev);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
522 return NULL;
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
523 };
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
524
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
525 data = index_deref(self, rev);
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
526 if (data == NULL)
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
527 return NULL;
47235
6b1eae313b2f revlogv2: store version information in the docket only
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47143
diff changeset
528 if (rev == 0 && self->format_version == format_v1) {
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
529 /* the header is eating the start of the first entry */
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
530 return PyBytes_FromStringAndSize(data + 4,
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
531 self->entry_size - 4);
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
532 }
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
533 return PyBytes_FromStringAndSize(data, self->entry_size);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
534 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
535
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
536 /*
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
537 * Return the hash of node corresponding to the given rev.
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
538 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
539 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
540 {
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
541 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
542 const char *data;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
543 const char *node_id;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
544
40960
43974cd44967 revlog: introduce a constant for nullrev in `revlog.c`
Boris Feld <boris.feld@octobus.net>
parents: 40862
diff changeset
545 if (pos == nullrev)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
546 return nullid;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
547
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
548 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
549 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
550
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
551 data = index_deref(self, pos);
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
552
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
553 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
554 node_id = data + entry_v1_offset_node_id;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
555 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
556 node_id = data + entry_v2_offset_node_id;
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
557 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
558 node_id = data + entry_cl2_offset_node_id;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
559 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
560 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
561 return NULL;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
562 }
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
563
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
564 return data ? node_id : NULL;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
565 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
566
37860
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
567 /*
48852
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
568 * Return the stored rank of a given revision if known, or rank_unknown
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
569 * otherwise.
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
570 *
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
571 * The rank of a revision is the size of the sub-graph it defines as a head.
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
572 * Equivalently, the rank of a revision `r` is the size of the set
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
573 * `ancestors(r)`, `r` included.
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
574 *
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
575 * This method returns the rank retrieved from the revlog in constant time. It
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
576 * makes no attempt at computing unknown values for versions of the revlog
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
577 * which do not persist the rank.
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
578 */
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
579 static int index_fast_rank(indexObject *self, Py_ssize_t pos)
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
580 {
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
581 Py_ssize_t length = index_length(self);
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
582 int rank;
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
583
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
584 if (self->format_version != format_cl2 || pos >= length) {
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
585 return rank_unknown;
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
586 }
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
587
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
588 if (pos == nullrev) {
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
589 return 0; /* convention */
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
590 }
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
591
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
592 return *(index_deref(self, pos) + entry_cl2_offset_rank);
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
593 }
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
594
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
595 /*
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
596 * Return the hash of the node corresponding to the given rev. The
37860
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
597 * 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: 37858
diff changeset
598 */
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
599 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: 37858
diff changeset
600 {
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
601 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: 37858
diff changeset
602 if (node == NULL) {
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
603 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: 37858
diff changeset
604 (int)pos);
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
605 }
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
606 return node;
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
607 }
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
608
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
609 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
610
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
611 static int node_check(Py_ssize_t nodelen, 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
612 {
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
613 Py_ssize_t thisnodelen;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
614 if (PyBytes_AsStringAndSize(obj, node, &thisnodelen) == -1)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
615 return -1;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
616 if (nodelen == thisnodelen)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
617 return 0;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
618 PyErr_Format(PyExc_ValueError, "node len %zd != expected node len %zd",
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
619 thisnodelen, nodelen);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
620 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
621 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
622
38850
6104b203bec8 index: replace insert(-1, e) method by append(e) method
Martin von Zweigbergk <martinvonz@google.com>
parents: 38848
diff changeset
623 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
624 {
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
625 uint64_t offset_flags, sidedata_offset;
47862
16346f3d446d revlog: fix type confusion with sidedata_comp_len (issue6580)
Julien Cristau <jcristau@mozilla.com>
parents: 47403
diff changeset
626 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2,
48499
52034c42c09d rank: add a "rank" value to the revlog-entry tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47863
diff changeset
627 sidedata_comp_len, rank;
47256
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
628 char data_comp_mode, sidedata_comp_mode;
47862
16346f3d446d revlog: fix type confusion with sidedata_comp_len (issue6580)
Julien Cristau <jcristau@mozilla.com>
parents: 47403
diff changeset
629 Py_ssize_t c_node_id_len;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
630 const char *c_node_id;
47256
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
631 char comp_field;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
632 char *data;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
633
47143
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
634 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len,
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
635 &uncomp_len, &base_rev, &link_rev, &parent_1,
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
636 &parent_2, &c_node_id, &c_node_id_len,
47249
130c9f7ed914 revlog: add a "data compression mode" entry in the index tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47235
diff changeset
637 &sidedata_offset, &sidedata_comp_len,
48499
52034c42c09d rank: add a "rank" value to the revlog-entry tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47863
diff changeset
638 &data_comp_mode, &sidedata_comp_mode, &rank)) {
52034c42c09d rank: add a "rank" value to the revlog-entry tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47863
diff changeset
639 PyErr_SetString(PyExc_TypeError, "12-tuple required");
47143
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
640 return NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
641 }
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
642
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
643 if (c_node_id_len != self->nodelen) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
644 PyErr_SetString(PyExc_TypeError, "invalid node");
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
645 return NULL;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
646 }
47256
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
647 if (self->format_version == format_v1) {
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
648
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
649 if (data_comp_mode != comp_mode_inline) {
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
650 PyErr_Format(PyExc_ValueError,
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
651 "invalid data compression mode: %i",
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
652 data_comp_mode);
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
653 return NULL;
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
654 }
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
655 if (sidedata_comp_mode != comp_mode_inline) {
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
656 PyErr_Format(PyExc_ValueError,
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
657 "invalid sidedata compression mode: %i",
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
658 sidedata_comp_mode);
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
659 return NULL;
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
660 }
47249
130c9f7ed914 revlog: add a "data compression mode" entry in the index tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47235
diff changeset
661 }
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
662
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
663 if (self->new_length == self->added_length) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
664 size_t new_added_length =
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
665 self->added_length ? self->added_length * 2 : 4096;
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
666 void *new_added = PyMem_Realloc(
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
667 self->added, new_added_length * self->entry_size);
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
668 if (!new_added)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
669 return PyErr_NoMemory();
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
670 self->added = new_added;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
671 self->added_length = new_added_length;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
672 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
673 rev = self->length + self->new_length;
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
674 data = self->added + self->entry_size * self->new_length++;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
675
48767
654baf1faa52 revlog: memset whole record instead of dealing with padding
pacien <pacien.trangirard@pacien.net>
parents: 48766
diff changeset
676 memset(data, 0, self->entry_size);
654baf1faa52 revlog: memset whole record instead of dealing with padding
pacien <pacien.trangirard@pacien.net>
parents: 48766
diff changeset
677
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
678 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
679 putbe32(offset_flags >> 32, data + entry_v1_offset_high);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
680 putbe32(offset_flags & 0xffffffffU,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
681 data + entry_v1_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
682 putbe32(comp_len, data + entry_v1_offset_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
683 putbe32(uncomp_len, data + entry_v1_offset_uncomp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
684 putbe32(base_rev, data + entry_v1_offset_base_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
685 putbe32(link_rev, data + entry_v1_offset_link_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
686 putbe32(parent_1, data + entry_v1_offset_parent_1);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
687 putbe32(parent_2, data + entry_v1_offset_parent_2);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
688 memcpy(data + entry_v1_offset_node_id, c_node_id,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
689 c_node_id_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
690 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
691 putbe32(offset_flags >> 32, data + entry_v2_offset_high);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
692 putbe32(offset_flags & 0xffffffffU,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
693 data + entry_v2_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
694 putbe32(comp_len, data + entry_v2_offset_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
695 putbe32(uncomp_len, data + entry_v2_offset_uncomp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
696 putbe32(base_rev, data + entry_v2_offset_base_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
697 putbe32(link_rev, data + entry_v2_offset_link_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
698 putbe32(parent_1, data + entry_v2_offset_parent_1);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
699 putbe32(parent_2, data + entry_v2_offset_parent_2);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
700 memcpy(data + entry_v2_offset_node_id, c_node_id,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
701 c_node_id_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
702 putbe64(sidedata_offset,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
703 data + entry_v2_offset_sidedata_offset);
48721
a9364de9be29 revlog: extract entry byte offsets into named constants
pacien <pacien.trangirard@pacien.net>
parents: 48499
diff changeset
704 putbe32(sidedata_comp_len,
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
705 data + entry_v2_offset_sidedata_comp_len);
47256
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
706 comp_field = data_comp_mode & 3;
2b69555e4875 revlog: introduce a compression mode for sidedata in the revlog index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47251
diff changeset
707 comp_field = comp_field | (sidedata_comp_mode & 3) << 2;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
708 data[entry_v2_offset_all_comp_mode] = comp_field;
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
709 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
710 putbe32(offset_flags >> 32, data + entry_cl2_offset_high);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
711 putbe32(offset_flags & 0xffffffffU,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
712 data + entry_cl2_offset_offset_flags);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
713 putbe32(comp_len, data + entry_cl2_offset_comp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
714 putbe32(uncomp_len, data + entry_cl2_offset_uncomp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
715 putbe32(parent_1, data + entry_cl2_offset_parent_1);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
716 putbe32(parent_2, data + entry_cl2_offset_parent_2);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
717 memcpy(data + entry_cl2_offset_node_id, c_node_id,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
718 c_node_id_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
719 putbe64(sidedata_offset,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
720 data + entry_cl2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
721 putbe32(sidedata_comp_len,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
722 data + entry_cl2_offset_sidedata_comp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
723 comp_field = data_comp_mode & 3;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
724 comp_field = comp_field | (sidedata_comp_mode & 3) << 2;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
725 data[entry_cl2_offset_all_comp_mode] = comp_field;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
726 putbe32(rank, data + entry_cl2_offset_rank);
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
727 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
728 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
729 return NULL;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
730 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
731
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
732 if (self->ntinitialized)
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
733 nt_insert(&self->nt, c_node_id, rev);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
734
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
735 Py_CLEAR(self->headrevs);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
736 Py_RETURN_NONE;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
737 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
738
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
739 /* Replace an existing index entry's sidedata offset and length with new ones.
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
740 This cannot be used outside of the context of sidedata rewriting,
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
741 inside the transaction that creates the given revision. */
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
742 static PyObject *index_replace_sidedata_info(indexObject *self, PyObject *args)
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
743 {
47078
223b47235d1c sidedata: enable sidedata computers to optionally rewrite flags
Raphaël Gomès <rgomes@octobus.net>
parents: 47037
diff changeset
744 uint64_t offset_flags, sidedata_offset;
47863
8d297f3563be revlog: fix more type confusion in index_replace_sidedata_info (issue6580)
Julien Cristau <jcristau@debian.org>
parents: 47862
diff changeset
745 Py_ssize_t rev;
8d297f3563be revlog: fix more type confusion in index_replace_sidedata_info (issue6580)
Julien Cristau <jcristau@debian.org>
parents: 47862
diff changeset
746 int sidedata_comp_len;
47259
07641bafa646 revlog: compress sidedata when doing "post-pull" sidedata update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47256
diff changeset
747 char comp_mode;
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
748 char *data;
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
749 #if LONG_MAX == 0x7fffffffL
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
750 const char *const sidedata_format = "nKiKB";
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
751 #else
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
752 const char *const sidedata_format = "nkikB";
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
753 #endif
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
754
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
755 if (self->entry_size == v1_entry_size || self->inlined) {
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
756 /*
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
757 There is a bug in the transaction handling when going from an
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
758 inline revlog to a separate index and data file. Turn it off until
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
759 it's fixed, since v2 revlogs sometimes get rewritten on exchange.
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
760 See issue6485.
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
761 */
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
762 raise_revlog_error();
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
763 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
764 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
765
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
766 if (!PyArg_ParseTuple(args, sidedata_format, &rev, &sidedata_offset,
47259
07641bafa646 revlog: compress sidedata when doing "post-pull" sidedata update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47256
diff changeset
767 &sidedata_comp_len, &offset_flags, &comp_mode))
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
768 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
769
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
770 if (rev < 0 || rev >= index_length(self)) {
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
771 PyErr_SetString(PyExc_IndexError, "revision outside index");
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
772 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
773 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
774 if (rev < self->length) {
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
775 PyErr_SetString(
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
776 PyExc_IndexError,
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
777 "cannot rewrite entries outside of this transaction");
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
778 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
779 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
780
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
781 /* Find the newly added node, offset from the "already on-disk" length
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
782 */
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
783 data = self->added + self->entry_size * (rev - self->length);
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
784 if (self->format_version == format_v2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
785 putbe64(offset_flags, data + entry_v2_offset_high);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
786 putbe64(sidedata_offset,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
787 data + entry_v2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
788 putbe32(sidedata_comp_len,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
789 data + entry_v2_offset_sidedata_comp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
790 data[entry_v2_offset_all_comp_mode] =
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
791 (data[entry_v2_offset_all_comp_mode] & ~(3 << 2)) |
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
792 ((comp_mode & 3) << 2);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
793 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
794 putbe64(offset_flags, data + entry_cl2_offset_high);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
795 putbe64(sidedata_offset,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
796 data + entry_cl2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
797 putbe32(sidedata_comp_len,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
798 data + entry_cl2_offset_sidedata_comp_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
799 data[entry_cl2_offset_all_comp_mode] =
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
800 (data[entry_cl2_offset_all_comp_mode] & ~(3 << 2)) |
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
801 ((comp_mode & 3) << 2);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
802 } else {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
803 raise_revlog_error();
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
804 return NULL;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
805 }
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
806
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
807 Py_RETURN_NONE;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
808 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
809
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
810 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
811 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
812 PyObject *obj = PyDict_New();
40455
88702fd208ce py3: convert revlog stats to a dict of (bytes, int) pairs
Yuya Nishihara <yuya@tcha.org>
parents: 40300
diff changeset
813 PyObject *s = NULL;
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
814 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
815
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
816 if (obj == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
817 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
818
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
819 #define istat(__n, __d) \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
820 do { \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
821 s = PyBytes_FromString(__d); \
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
822 t = PyLong_FromSsize_t(self->__n); \
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
823 if (!s || !t) \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
824 goto bail; \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
825 if (PyDict_SetItem(obj, s, t) == -1) \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
826 goto bail; \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
827 Py_CLEAR(s); \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
828 Py_CLEAR(t); \
28792
507136150d2b parsers: fix istat macro to work with single line if statement
Matt Fowles <matt.fowles@gmail.com>
parents: 28386
diff changeset
829 } while (0)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
830
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
831 if (self->added_length)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
832 istat(new_length, "index entries added");
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
833 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
834 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
835 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
836 istat(ntrev, "node trie last rev scanned");
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
837 if (self->ntinitialized) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
838 istat(nt.capacity, "node trie capacity");
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
839 istat(nt.depth, "node trie depth");
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
840 istat(nt.length, "node trie count");
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
841 istat(nt.splits, "node trie splits");
38913
c2c253558e3c index: move more fields onto nodetree type
Martin von Zweigbergk <martinvonz@google.com>
parents: 38912
diff changeset
842 }
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
843
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
844 #undef istat
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
845
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
846 return obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
847
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
848 bail:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
849 Py_XDECREF(obj);
40455
88702fd208ce py3: convert revlog stats to a dict of (bytes, int) pairs
Yuya Nishihara <yuya@tcha.org>
parents: 40300
diff changeset
850 Py_XDECREF(s);
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
851 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
852 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
853 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
854
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
855 /*
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
856 * 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
857 * the cached copy.
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
858 */
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
859 static PyObject *list_copy(PyObject *list)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
860 {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
861 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
862 PyObject *newlist = PyList_New(len);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
863 Py_ssize_t i;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
864
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
865 if (newlist == NULL)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
866 return NULL;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
867
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
868 for (i = 0; i < len; i++) {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
869 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
870 Py_INCREF(obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
871 PyList_SET_ITEM(newlist, i, obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
872 }
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
873
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
874 return newlist;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
875 }
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
876
34440
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
877 static int check_filter(PyObject *filter, Py_ssize_t arg)
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
878 {
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
879 if (filter) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
880 PyObject *arglist, *result;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
881 int isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
882
26107
50582df9d7a7 parsers: fix two cases of unsigned long instead of Py_ssize_t
Augie Fackler <augie@google.com>
parents: 26098
diff changeset
883 arglist = Py_BuildValue("(n)", arg);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
884 if (!arglist) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
885 return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
886 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
887
46260
abba2d365373 revlog: migrate from PyEval_CallObject to PyObject_Call
Augie Fackler <augie@google.com>
parents: 46224
diff changeset
888 result = PyObject_Call(filter, arglist, NULL);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
889 Py_DECREF(arglist);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
890 if (!result) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
891 return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
892 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
893
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
894 /* 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
895 * 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
896 isfiltered = PyObject_IsTrue(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
897 Py_DECREF(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
898 return isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
899 } else {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
900 return 0;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
901 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
902 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
903
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
904 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
905 int parent_2, Py_ssize_t i)
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
906 {
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
907 if (parent_1 >= 0 && phases[parent_1] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
908 phases[i] = phases[parent_1];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
909 if (parent_2 >= 0 && phases[parent_2] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
910 phases[i] = phases[parent_2];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
911 }
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
912
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
913 static PyObject *reachableroots2(indexObject *self, PyObject *args)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
914 {
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
915
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
916 /* Input */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
917 long minroot;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
918 PyObject *includepatharg = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
919 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
920 /* heads and roots are lists */
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
921 PyObject *heads = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
922 PyObject *roots = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
923 PyObject *reachable = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
924
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
925 PyObject *val;
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
926 Py_ssize_t len = index_length(self);
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
927 long revnum;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
928 Py_ssize_t k;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
929 Py_ssize_t i;
26042
2a3010ba6f52 reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents: 26041
diff changeset
930 Py_ssize_t l;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
931 int r;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
932 int parents[2];
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
933
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
934 /* Internal data structure:
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
935 * tovisit: array of length len+1 (all revs + nullrev), filled upto
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
936 * lentovisit
40561
5c14bf0c5be3 revlog: add blank line in comment to help clang-format
Augie Fackler <augie@google.com>
parents: 40560
diff changeset
937 *
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
938 * 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
939 int *tovisit = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
940 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
941 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
942 char *revstates = NULL;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
943
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
944 /* Get arguments */
26009
bbb698697efc reachableroots: fix transposition of set and list types in PyArg_ParseTuple
Augie Fackler <augie@google.com>
parents: 26008
diff changeset
945 if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
946 &PyList_Type, &roots, &PyBool_Type,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
947 &includepatharg))
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
948 goto bail;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
949
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
950 if (includepatharg == Py_True)
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
951 includepath = 1;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
952
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
953 /* Initialize return set */
26055
607868eccaa7 reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents: 26054
diff changeset
954 reachable = PyList_New(0);
607868eccaa7 reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents: 26054
diff changeset
955 if (reachable == NULL)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
956 goto bail;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
957
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
958 /* Initialize internal datastructures */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
959 tovisit = (int *)malloc((len + 1) * sizeof(int));
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
960 if (tovisit == NULL) {
26008
59d57ea69ae6 reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents: 26007
diff changeset
961 PyErr_NoMemory();
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
962 goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
963 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
964
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
965 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
966 if (revstates == NULL) {
26008
59d57ea69ae6 reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents: 26007
diff changeset
967 PyErr_NoMemory();
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
968 goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
969 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
970
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
971 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
972 for (i = 0; i < l; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
973 revnum = PyLong_AsLong(PyList_GET_ITEM(roots, i));
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
974 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
975 goto bail;
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
976 /* 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
977 * 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
978 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
979 continue;
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
980 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
981 }
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
982
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
983 /* 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
984 l = PyList_GET_SIZE(heads);
2a3010ba6f52 reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents: 26041
diff changeset
985 for (i = 0; i < l; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
986 revnum = PyLong_AsLong(PyList_GET_ITEM(heads, i));
26018
c6115c30a376 reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents: 26017
diff changeset
987 if (revnum == -1 && PyErr_Occurred())
c6115c30a376 reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents: 26017
diff changeset
988 goto bail;
26017
44705659da94 reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents: 26016
diff changeset
989 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
990 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
991 goto bail;
44705659da94 reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents: 26016
diff changeset
992 }
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
993 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
994 tovisit[lentovisit++] = (int)revnum;
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
995 revstates[revnum + 1] |= RS_SEEN;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
996 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
997 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
998
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
999 /* Visit the tovisit list and find the reachable roots */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1000 k = 0;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1001 while (k < lentovisit) {
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1002 /* 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
1003 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
1004 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
1005 revstates[revnum + 1] |= RS_REACHABLE;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1006 val = PyLong_FromLong(revnum);
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
1007 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
1008 goto bail;
26058
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
1009 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
1010 Py_DECREF(val);
26058
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
1011 if (r < 0)
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
1012 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
1013 if (includepath == 0)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1014 continue;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1015 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1016
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1017 /* Add its parents to the list of nodes to visit */
40960
43974cd44967 revlog: introduce a constant for nullrev in `revlog.c`
Boris Feld <boris.feld@octobus.net>
parents: 40862
diff changeset
1018 if (revnum == nullrev)
26041
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1019 continue;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1020 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
1021 if (r < 0)
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1022 goto bail;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1023 for (i = 0; i < 2; i++) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1024 if (!(revstates[parents[i] + 1] & RS_SEEN) &&
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1025 parents[i] >= minroot) {
26041
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1026 tovisit[lentovisit++] = parents[i];
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
1027 revstates[parents[i] + 1] |= RS_SEEN;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1028 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1029 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1030 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1031
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1032 /* 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
1033 * and add them to the reachable set */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1034 if (includepath == 1) {
26080
83c9edcac05c reachableroots: silence warning of implicit integer narrowing issued by clang
Yuya Nishihara <yuya@tcha.org>
parents: 26079
diff changeset
1035 long minidx = minroot;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1036 if (minidx < 0)
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1037 minidx = 0;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1038 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
1039 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
1040 continue;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1041 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
1042 /* 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
1043 * index_get_parents */
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1044 if (r < 0)
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1045 goto bail;
26059
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1046 if (((revstates[parents[0] + 1] |
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1047 revstates[parents[1] + 1]) &
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1048 RS_REACHABLE) &&
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1049 !(revstates[i + 1] & RS_REACHABLE)) {
26059
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1050 revstates[i + 1] |= RS_REACHABLE;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1051 val = PyLong_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
1052 if (val == NULL)
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1053 goto bail;
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1054 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
1055 Py_DECREF(val);
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1056 if (r < 0)
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1057 goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1058 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1059 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1060 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1061
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
1062 free(revstates);
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1063 free(tovisit);
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1064 return reachable;
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
1065 bail:
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1066 Py_XDECREF(reachable);
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
1067 free(revstates);
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
1068 free(tovisit);
26010
2c03e521a0c5 reachableroots: return NULL if we're throwing an exception
Augie Fackler <augie@google.com>
parents: 26009
diff changeset
1069 return NULL;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1070 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1071
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1072 static int add_roots_get_min(indexObject *self, PyObject *roots, char *phases,
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1073 char phase)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1074 {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1075 Py_ssize_t len = index_length(self);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1076 PyObject *item;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1077 PyObject *iterator;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1078 int rev, minrev = -1;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1079 char *node;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1080
45175
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1081 if (!PySet_Check(roots)) {
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1082 PyErr_SetString(PyExc_TypeError,
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1083 "roots must be a set of nodes");
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1084 return -2;
45175
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1085 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1086 iterator = PyObject_GetIter(roots);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1087 if (iterator == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1088 return -2;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1089 while ((item = PyIter_Next(iterator))) {
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1090 if (node_check(self->nodelen, item, &node) == -1)
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1091 goto failed;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1092 rev = index_find_node(self, node);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1093 /* null is implicitly public, so negative is invalid */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1094 if (rev < 0 || rev >= len)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1095 goto failed;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1096 phases[rev] = phase;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1097 if (minrev == -1 || minrev > rev)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1098 minrev = rev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1099 Py_DECREF(item);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1100 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1101 Py_DECREF(iterator);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1102 return minrev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1103 failed:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1104 Py_DECREF(iterator);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1105 Py_DECREF(item);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1106 return -2;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1107 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1108
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
1109 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
1110 {
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1111 /* 0: public (untracked), 1: draft, 2: secret, 32: archive,
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1112 96: internal */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1113 static const char trackedphases[] = {1, 2, 32, 96};
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1114 PyObject *roots = Py_None;
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1115 PyObject *phasesetsdict = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1116 PyObject *phasesets[4] = {NULL, NULL, NULL, NULL};
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
1117 Py_ssize_t len = index_length(self);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1118 char *phases = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1119 int minphaserev = -1, rev, i;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1120 const int numphases = (int)(sizeof(phasesets) / sizeof(phasesets[0]));
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1121
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1122 if (!PyArg_ParseTuple(args, "O", &roots))
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1123 return NULL;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1124 if (roots == NULL || !PyDict_Check(roots)) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1125 PyErr_SetString(PyExc_TypeError, "roots must be a dictionary");
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1126 return NULL;
36623
a472a897c340 cext: fix computephasesmapsets() not to return without setting an exception
Yuya Nishihara <yuya@tcha.org>
parents: 36621
diff changeset
1127 }
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1128
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1129 phases = calloc(len, 1);
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1130 if (phases == NULL) {
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1131 PyErr_NoMemory();
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1132 return NULL;
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1133 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1134
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1135 for (i = 0; i < numphases; ++i) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1136 PyObject *pyphase = PyLong_FromLong(trackedphases[i]);
45180
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
1137 PyObject *phaseroots = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1138 if (pyphase == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1139 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1140 phaseroots = PyDict_GetItem(roots, pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1141 Py_DECREF(pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1142 if (phaseroots == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1143 continue;
45176
3264d58e8b06 phases: fix clang-format error
Yuya Nishihara <yuya@tcha.org>
parents: 45175
diff changeset
1144 rev = add_roots_get_min(self, phaseroots, phases,
3264d58e8b06 phases: fix clang-format error
Yuya Nishihara <yuya@tcha.org>
parents: 45175
diff changeset
1145 trackedphases[i]);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1146 if (rev == -2)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1147 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1148 if (rev != -1 && (minphaserev == -1 || rev < minphaserev))
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1149 minphaserev = rev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1150 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1151
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1152 for (i = 0; i < numphases; ++i) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1153 phasesets[i] = PySet_New(NULL);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1154 if (phasesets[i] == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1155 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1156 }
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
1157
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1158 if (minphaserev == -1)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1159 minphaserev = len;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1160 for (rev = minphaserev; rev < len; ++rev) {
45180
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
1161 PyObject *pyphase = NULL;
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
1162 PyObject *pyrev = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1163 int parents[2];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1164 /*
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1165 * The parent lookup could be skipped for phaseroots, but
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1166 * phase --force would historically not recompute them
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1167 * correctly, leaving descendents with a lower phase around.
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1168 * As such, unconditionally recompute the phase.
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1169 */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1170 if (index_get_parents(self, rev, parents, (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
1171 goto release;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1172 set_phase_from_parents(phases, parents[0], parents[1], rev);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1173 switch (phases[rev]) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1174 case 0:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1175 continue;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1176 case 1:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1177 pyphase = phasesets[0];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1178 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1179 case 2:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1180 pyphase = phasesets[1];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1181 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1182 case 32:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1183 pyphase = phasesets[2];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1184 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1185 case 96:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1186 pyphase = phasesets[3];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1187 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1188 default:
45177
03332e5f67e9 phases: make sure an exception should be set on error return
Yuya Nishihara <yuya@tcha.org>
parents: 45176
diff changeset
1189 /* this should never happen since the phase number is
03332e5f67e9 phases: make sure an exception should be set on error return
Yuya Nishihara <yuya@tcha.org>
parents: 45176
diff changeset
1190 * specified by this function. */
03332e5f67e9 phases: make sure an exception should be set on error return
Yuya Nishihara <yuya@tcha.org>
parents: 45176
diff changeset
1191 PyErr_SetString(PyExc_SystemError,
03332e5f67e9 phases: make sure an exception should be set on error return
Yuya Nishihara <yuya@tcha.org>
parents: 45176
diff changeset
1192 "bad phase number in internal list");
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1193 goto release;
36623
a472a897c340 cext: fix computephasesmapsets() not to return without setting an exception
Yuya Nishihara <yuya@tcha.org>
parents: 36621
diff changeset
1194 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1195 pyrev = PyLong_FromLong(rev);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1196 if (pyrev == NULL)
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1197 goto release;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1198 if (PySet_Add(pyphase, pyrev) == -1) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1199 Py_DECREF(pyrev);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1200 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1201 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1202 Py_DECREF(pyrev);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1203 }
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1204
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1205 phasesetsdict = _dict_new_presized(numphases);
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1206 if (phasesetsdict == NULL)
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1207 goto release;
45141
9719e118e4af cext: remove unused variables
Joerg Sonnenberger <joerg@bec.de>
parents: 45131
diff changeset
1208 for (i = 0; i < numphases; ++i) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1209 PyObject *pyphase = PyLong_FromLong(trackedphases[i]);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1210 if (pyphase == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1211 goto release;
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1212 if (PyDict_SetItem(phasesetsdict, pyphase, phasesets[i]) ==
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1213 -1) {
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1214 Py_DECREF(pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1215 goto release;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1216 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1217 Py_DECREF(phasesets[i]);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1218 phasesets[i] = NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1219 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1220
47343
9f798c1b0d89 cext: fix memory leak in phases computation
Georges Racinet <georges.racinet@octobus.net>
parents: 46974
diff changeset
1221 free(phases);
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1222 return Py_BuildValue("nN", len, phasesetsdict);
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
1223
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1224 release:
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1225 for (i = 0; i < numphases; ++i)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1226 Py_XDECREF(phasesets[i]);
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1227 Py_XDECREF(phasesetsdict);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1228
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1229 free(phases);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1230 return NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1231 }
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1232
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1233 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
1234 {
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1235 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
1236 char *nothead = NULL;
22540
9a860ac8c216 parsers: fix uninitialize variable warning
David Soria Parra <davidsp@fb.com>
parents: 22484
diff changeset
1237 PyObject *heads = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1238 PyObject *filter = NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1239 PyObject *filteredrevs = Py_None;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1240
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1241 if (!PyArg_ParseTuple(args, "|O", &filteredrevs)) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1242 return NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1243 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1244
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1245 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
1246 return list_copy(self->headrevs);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
1247
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1248 Py_DECREF(self->filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1249 self->filteredrevs = filteredrevs;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1250 Py_INCREF(filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1251
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1252 if (filteredrevs != Py_None) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1253 filter = PyObject_GetAttrString(filteredrevs, "__contains__");
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1254 if (!filter) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1255 PyErr_SetString(
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1256 PyExc_TypeError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1257 "filteredrevs has no attribute __contains__");
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1258 goto bail;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1259 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1260 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1261
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
1262 len = index_length(self);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1263 heads = PyList_New(0);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1264 if (heads == NULL)
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1265 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1266 if (len == 0) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1267 PyObject *nullid = PyLong_FromLong(-1);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1268 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
1269 Py_XDECREF(nullid);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1270 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1271 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1272 goto done;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1273 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1274
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1275 nothead = calloc(len, 1);
27366
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
1276 if (nothead == NULL) {
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
1277 PyErr_NoMemory();
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1278 goto bail;
27366
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
1279 }
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1280
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1281 for (i = len - 1; i >= 0; i--) {
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1282 int isfiltered;
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1283 int parents[2];
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1284
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1285 /* If nothead[i] == 1, it means we've seen an unfiltered child
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1286 * of this node already, and therefore this node is not
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1287 * filtered. So we can skip the expensive check_filter step.
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1288 */
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1289 if (nothead[i] != 1) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1290 isfiltered = check_filter(filter, i);
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1291 if (isfiltered == -1) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1292 PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1293 "unable to check filter");
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1294 goto bail;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1295 }
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1296
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1297 if (isfiltered) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1298 nothead[i] = 1;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1299 continue;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1300 }
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1301 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1302
25860
895f04955a49 parsers: silence warning of implicit integer conversion issued by clang
Yuya Nishihara <yuya@tcha.org>
parents: 25810
diff changeset
1303 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
1304 goto bail;
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1305 for (j = 0; j < 2; j++) {
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1306 if (parents[j] >= 0)
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1307 nothead[parents[j]] = 1;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1308 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1309 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1310
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1311 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
1312 PyObject *head;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1313
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1314 if (nothead[i])
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1315 continue;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1316 head = PyLong_FromSsize_t(i);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1317 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
1318 Py_XDECREF(head);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1319 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1320 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1321 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1322
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1323 done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
1324 self->headrevs = heads;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1325 Py_XDECREF(filter);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1326 free(nothead);
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
1327 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
1328 bail:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1329 Py_XDECREF(filter);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1330 Py_XDECREF(heads);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1331 free(nothead);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1332 return NULL;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1333 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1334
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1335 /**
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1336 * Obtain the base revision index entry.
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1337 *
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1338 * Callers must ensure that rev >= 0 or illegal memory access may occur.
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1339 */
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1340 static inline int index_baserev(indexObject *self, int rev)
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1341 {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1342 const char *data;
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1343 int result;
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1344
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
1345 data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
1346 if (data == NULL)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
1347 return -2;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1348
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1349 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1350 result = getbe32(data + entry_v1_offset_base_rev);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1351 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1352 result = getbe32(data + entry_v2_offset_base_rev);
48768
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
1353 } else if (self->format_version == format_cl2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
1354 return rev;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1355 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1356 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1357 return -1;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1358 }
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1359
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1360 if (result > rev) {
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1361 PyErr_Format(
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1362 PyExc_ValueError,
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1363 "corrupted revlog, revision base above revision: %d, %d",
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1364 rev, result);
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1365 return -2;
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1366 }
41019
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1367 if (result < -1) {
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1368 PyErr_Format(
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1369 PyExc_ValueError,
41283
4948b327d3b9 cext: clang-format new code coming from stable branch
Yuya Nishihara <yuya@tcha.org>
parents: 41129
diff changeset
1370 "corrupted revlog, revision base out of range: %d, %d", rev,
4948b327d3b9 cext: clang-format new code coming from stable branch
Yuya Nishihara <yuya@tcha.org>
parents: 41129
diff changeset
1371 result);
41019
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1372 return -2;
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1373 }
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1374 return result;
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1375 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1376
41085
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1377 /**
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1378 * Find if a revision is a snapshot or not
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1379 *
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1380 * Only relevant for sparse-revlog case.
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1381 * Callers must ensure that rev is in a valid range.
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1382 */
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1383 static int index_issnapshotrev(indexObject *self, Py_ssize_t rev)
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1384 {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1385 int ps[2];
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1386 Py_ssize_t base;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1387 while (rev >= 0) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1388 base = (Py_ssize_t)index_baserev(self, rev);
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1389 if (base == rev) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1390 base = -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1391 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1392 if (base == -2) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1393 assert(PyErr_Occurred());
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1394 return -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1395 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1396 if (base == -1) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1397 return 1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1398 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1399 if (index_get_parents(self, rev, ps, (int)rev) < 0) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1400 assert(PyErr_Occurred());
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1401 return -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1402 };
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1403 if (base == ps[0] || base == ps[1]) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1404 return 0;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1405 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1406 rev = base;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1407 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1408 return rev == -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1409 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1410
41086
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1411 static PyObject *index_issnapshot(indexObject *self, PyObject *value)
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1412 {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1413 long rev;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1414 int issnap;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1415 Py_ssize_t length = index_length(self);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1416
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1417 if (!pylong_to_long(value, &rev)) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1418 return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1419 }
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1420 if (rev < -1 || rev >= length) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1421 PyErr_Format(PyExc_ValueError, "revlog index out of range: %ld",
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1422 rev);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1423 return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1424 };
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1425 issnap = index_issnapshotrev(self, (Py_ssize_t)rev);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1426 if (issnap < 0) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1427 return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1428 };
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1429 return PyBool_FromLong((long)issnap);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1430 }
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1431
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1432 static PyObject *index_findsnapshots(indexObject *self, PyObject *args)
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1433 {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1434 Py_ssize_t start_rev;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1435 PyObject *cache;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1436 Py_ssize_t base;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1437 Py_ssize_t rev;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1438 PyObject *key = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1439 PyObject *value = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1440 const Py_ssize_t length = index_length(self);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1441 if (!PyArg_ParseTuple(args, "O!n", &PyDict_Type, &cache, &start_rev)) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1442 return NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1443 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1444 for (rev = start_rev; rev < length; rev++) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1445 int issnap;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1446 PyObject *allvalues = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1447 issnap = index_issnapshotrev(self, rev);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1448 if (issnap < 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1449 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1450 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1451 if (issnap == 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1452 continue;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1453 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1454 base = (Py_ssize_t)index_baserev(self, rev);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1455 if (base == rev) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1456 base = -1;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1457 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1458 if (base == -2) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1459 assert(PyErr_Occurred());
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1460 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1461 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1462 key = PyLong_FromSsize_t(base);
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1463 allvalues = PyDict_GetItem(cache, key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1464 if (allvalues == NULL && PyErr_Occurred()) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1465 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1466 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1467 if (allvalues == NULL) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1468 int r;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1469 allvalues = PyList_New(0);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1470 if (!allvalues) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1471 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1472 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1473 r = PyDict_SetItem(cache, key, allvalues);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1474 Py_DECREF(allvalues);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1475 if (r < 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1476 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1477 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1478 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1479 value = PyLong_FromSsize_t(rev);
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1480 if (PyList_Append(allvalues, value)) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1481 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1482 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1483 Py_CLEAR(key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1484 Py_CLEAR(value);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1485 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1486 Py_RETURN_NONE;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1487 bail:
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1488 Py_XDECREF(key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1489 Py_XDECREF(value);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1490 return NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1491 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1492
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1493 static PyObject *index_deltachain(indexObject *self, PyObject *args)
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1494 {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1495 int rev, generaldelta;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1496 PyObject *stoparg;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1497 int stoprev, iterrev, baserev = -1;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1498 int stopped;
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1499 PyObject *chain = NULL, *result = NULL;
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
1500 const Py_ssize_t length = index_length(self);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1501
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1502 if (!PyArg_ParseTuple(args, "iOi", &rev, &stoparg, &generaldelta)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1503 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1504 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1505
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1506 if (PyLong_Check(stoparg)) {
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1507 stoprev = (int)PyLong_AsLong(stoparg);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1508 if (stoprev == -1 && PyErr_Occurred()) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1509 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1510 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1511 } else if (stoparg == Py_None) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1512 stoprev = -2;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1513 } else {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1514 PyErr_SetString(PyExc_ValueError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1515 "stoprev must be integer or None");
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1516 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1517 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1518
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
1519 if (rev < 0 || rev >= length) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1520 PyErr_SetString(PyExc_ValueError, "revlog index out of range");
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1521 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1522 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1523
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1524 chain = PyList_New(0);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1525 if (chain == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1526 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1527 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1528
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1529 baserev = index_baserev(self, rev);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1530
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1531 /* This should never happen. */
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1532 if (baserev <= -2) {
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1533 /* Error should be set by index_deref() */
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1534 assert(PyErr_Occurred());
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1535 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1536 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1537
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1538 iterrev = rev;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1539
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1540 while (iterrev != baserev && iterrev != stoprev) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1541 PyObject *value = PyLong_FromLong(iterrev);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1542 if (value == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1543 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1544 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1545 if (PyList_Append(chain, value)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1546 Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1547 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1548 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1549 Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1550
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1551 if (generaldelta) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1552 iterrev = baserev;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1553 } else {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1554 iterrev--;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1555 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1556
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1557 if (iterrev < 0) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1558 break;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1559 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1560
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
1561 if (iterrev >= length) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1562 PyErr_SetString(PyExc_IndexError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1563 "revision outside index");
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1564 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1565 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1566
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1567 baserev = index_baserev(self, iterrev);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1568
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1569 /* This should never happen. */
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1570 if (baserev <= -2) {
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1571 /* Error should be set by index_deref() */
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1572 assert(PyErr_Occurred());
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1573 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1574 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1575 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1576
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1577 if (iterrev == stoprev) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1578 stopped = 1;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1579 } else {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1580 PyObject *value = PyLong_FromLong(iterrev);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1581 if (value == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1582 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1583 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1584 if (PyList_Append(chain, value)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1585 Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1586 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1587 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1588 Py_DECREF(value);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1589
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1590 stopped = 0;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1591 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1592
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1593 if (PyList_Reverse(chain)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1594 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1595 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1596
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1597 result = Py_BuildValue("OO", chain, stopped ? Py_True : Py_False);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1598 Py_DECREF(chain);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1599 return result;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1600
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1601 bail:
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1602 Py_DECREF(chain);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1603 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1604 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1605
40705
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1606 static inline int64_t
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1607 index_segment_span(indexObject *self, Py_ssize_t start_rev, Py_ssize_t end_rev)
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1608 {
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1609 int64_t start_offset;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1610 int64_t end_offset;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1611 int end_size;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1612 start_offset = index_get_start(self, start_rev);
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1613 if (start_offset < 0) {
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1614 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1615 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1616 end_offset = index_get_start(self, end_rev);
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1617 if (end_offset < 0) {
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1618 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1619 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1620 end_size = index_get_length(self, end_rev);
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1621 if (end_size < 0) {
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1622 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1623 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1624 if (end_offset < start_offset) {
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1625 PyErr_Format(PyExc_ValueError,
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1626 "corrupted revlog index: inconsistent offset "
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1627 "between revisions (%zd) and (%zd)",
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1628 start_rev, end_rev);
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1629 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1630 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1631 return (end_offset - start_offset) + (int64_t)end_size;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1632 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1633
40742
8edca70dc951 revlog: update the documentation for `trim_endidx`
Boris Feld <boris.feld@octobus.net>
parents: 40741
diff changeset
1634 /* returns endidx so that revs[startidx:endidx] has no empty trailing revs */
40706
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1635 static Py_ssize_t trim_endidx(indexObject *self, const Py_ssize_t *revs,
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1636 Py_ssize_t startidx, Py_ssize_t endidx)
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1637 {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1638 int length;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1639 while (endidx > 1 && endidx > startidx) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1640 length = index_get_length(self, revs[endidx - 1]);
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1641 if (length < 0) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1642 return -1;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1643 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1644 if (length != 0) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1645 break;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1646 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1647 endidx -= 1;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1648 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1649 return endidx;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1650 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1651
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1652 struct Gap {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1653 int64_t size;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1654 Py_ssize_t idx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1655 };
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1656
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1657 static int gap_compare(const void *left, const void *right)
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1658 {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1659 const struct Gap *l_left = ((const struct Gap *)left);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1660 const struct Gap *l_right = ((const struct Gap *)right);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1661 if (l_left->size < l_right->size) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1662 return -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1663 } else if (l_left->size > l_right->size) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1664 return 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1665 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1666 return 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1667 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1668 static int Py_ssize_t_compare(const void *left, const void *right)
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1669 {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1670 const Py_ssize_t l_left = *(const Py_ssize_t *)left;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1671 const Py_ssize_t l_right = *(const Py_ssize_t *)right;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1672 if (l_left < l_right) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1673 return -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1674 } else if (l_left > l_right) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1675 return 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1676 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1677 return 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1678 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1679
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1680 static PyObject *index_slicechunktodensity(indexObject *self, PyObject *args)
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1681 {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1682 /* method arguments */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1683 PyObject *list_revs = NULL; /* revisions in the chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1684 double targetdensity = 0; /* min density to achieve */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1685 Py_ssize_t mingapsize = 0; /* threshold to ignore gaps */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1686
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1687 /* other core variables */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1688 Py_ssize_t idxlen = index_length(self);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1689 Py_ssize_t i; /* used for various iteration */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1690 PyObject *result = NULL; /* the final return of the function */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1691
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1692 /* generic information about the delta chain being slice */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1693 Py_ssize_t num_revs = 0; /* size of the full delta chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1694 Py_ssize_t *revs = NULL; /* native array of revision in the chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1695 int64_t chainpayload = 0; /* sum of all delta in the chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1696 int64_t deltachainspan = 0; /* distance from first byte to last byte */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1697
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1698 /* variable used for slicing the delta chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1699 int64_t readdata = 0; /* amount of data currently planned to be read */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1700 double density = 0; /* ration of payload data compared to read ones */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1701 int64_t previous_end;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1702 struct Gap *gaps = NULL; /* array of notable gap in the chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1703 Py_ssize_t num_gaps =
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1704 0; /* total number of notable gap recorded so far */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1705 Py_ssize_t *selected_indices = NULL; /* indices of gap skipped over */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1706 Py_ssize_t num_selected = 0; /* number of gaps skipped */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1707 PyObject *chunk = NULL; /* individual slice */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1708 PyObject *allchunks = NULL; /* all slices */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1709 Py_ssize_t previdx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1710
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1711 /* parsing argument */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1712 if (!PyArg_ParseTuple(args, "O!dn", &PyList_Type, &list_revs,
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1713 &targetdensity, &mingapsize)) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1714 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1715 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1716
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1717 /* If the delta chain contains a single element, we do not need slicing
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1718 */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1719 num_revs = PyList_GET_SIZE(list_revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1720 if (num_revs <= 1) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1721 result = PyTuple_Pack(1, list_revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1722 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1723 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1724
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1725 /* Turn the python list into a native integer array (for efficiency) */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1726 revs = (Py_ssize_t *)calloc(num_revs, sizeof(Py_ssize_t));
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1727 if (revs == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1728 PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1729 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1730 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1731 for (i = 0; i < num_revs; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1732 Py_ssize_t revnum =
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1733 PyLong_AsLong(PyList_GET_ITEM(list_revs, i));
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1734 if (revnum == -1 && PyErr_Occurred()) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1735 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1736 }
40963
2e305e54eae3 sparse-revlog: protect C code against delta chain including nullrev
Boris Feld <boris.feld@octobus.net>
parents: 40962
diff changeset
1737 if (revnum < nullrev || revnum >= idxlen) {
40756
c85964d715fd sparse: raise a move verbose index error from the C code
Boris Feld <boris.feld@octobus.net>
parents: 40742
diff changeset
1738 PyErr_Format(PyExc_IndexError,
c85964d715fd sparse: raise a move verbose index error from the C code
Boris Feld <boris.feld@octobus.net>
parents: 40742
diff changeset
1739 "index out of range: %zd", revnum);
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1740 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1741 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1742 revs[i] = revnum;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1743 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1744
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1745 /* Compute and check various property of the unsliced delta chain */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1746 deltachainspan = index_segment_span(self, revs[0], revs[num_revs - 1]);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1747 if (deltachainspan < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1748 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1749 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1750
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1751 if (deltachainspan <= mingapsize) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1752 result = PyTuple_Pack(1, list_revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1753 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1754 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1755 chainpayload = 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1756 for (i = 0; i < num_revs; i++) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1757 int tmp = index_get_length(self, revs[i]);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1758 if (tmp < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1759 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1760 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1761 chainpayload += tmp;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1762 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1763
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1764 readdata = deltachainspan;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1765 density = 1.0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1766
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1767 if (0 < deltachainspan) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1768 density = (double)chainpayload / (double)deltachainspan;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1769 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1770
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1771 if (density >= targetdensity) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1772 result = PyTuple_Pack(1, list_revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1773 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1774 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1775
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1776 /* if chain is too sparse, look for relevant gaps */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1777 gaps = (struct Gap *)calloc(num_revs, sizeof(struct Gap));
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1778 if (gaps == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1779 PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1780 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1781 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1782
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1783 previous_end = -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1784 for (i = 0; i < num_revs; i++) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1785 int64_t revstart;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1786 int revsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1787 revstart = index_get_start(self, revs[i]);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1788 if (revstart < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1789 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1790 };
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1791 revsize = index_get_length(self, revs[i]);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1792 if (revsize < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1793 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1794 };
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1795 if (revsize == 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1796 continue;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1797 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1798 if (previous_end >= 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1799 int64_t gapsize = revstart - previous_end;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1800 if (gapsize > mingapsize) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1801 gaps[num_gaps].size = gapsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1802 gaps[num_gaps].idx = i;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1803 num_gaps += 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1804 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1805 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1806 previous_end = revstart + revsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1807 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1808 if (num_gaps == 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1809 result = PyTuple_Pack(1, list_revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1810 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1811 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1812 qsort(gaps, num_gaps, sizeof(struct Gap), &gap_compare);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1813
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1814 /* Slice the largest gap first, they improve the density the most */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1815 selected_indices =
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1816 (Py_ssize_t *)malloc((num_gaps + 1) * sizeof(Py_ssize_t));
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1817 if (selected_indices == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1818 PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1819 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1820 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1821
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1822 for (i = num_gaps - 1; i >= 0; i--) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1823 selected_indices[num_selected] = gaps[i].idx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1824 readdata -= gaps[i].size;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1825 num_selected += 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1826 if (readdata <= 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1827 density = 1.0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1828 } else {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1829 density = (double)chainpayload / (double)readdata;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1830 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1831 if (density >= targetdensity) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1832 break;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1833 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1834 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1835 qsort(selected_indices, num_selected, sizeof(Py_ssize_t),
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1836 &Py_ssize_t_compare);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1837
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1838 /* create the resulting slice */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1839 allchunks = PyList_New(0);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1840 if (allchunks == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1841 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1842 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1843 previdx = 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1844 selected_indices[num_selected] = num_revs;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1845 for (i = 0; i <= num_selected; i++) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1846 Py_ssize_t idx = selected_indices[i];
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1847 Py_ssize_t endidx = trim_endidx(self, revs, previdx, idx);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1848 if (endidx < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1849 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1850 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1851 if (previdx < endidx) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1852 chunk = PyList_GetSlice(list_revs, previdx, endidx);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1853 if (chunk == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1854 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1855 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1856 if (PyList_Append(allchunks, chunk) == -1) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1857 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1858 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1859 Py_DECREF(chunk);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1860 chunk = NULL;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1861 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1862 previdx = idx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1863 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1864 result = allchunks;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1865 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1866
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1867 bail:
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1868 Py_XDECREF(allchunks);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1869 Py_XDECREF(chunk);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1870 done:
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1871 free(revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1872 free(gaps);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1873 free(selected_indices);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1874 return result;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1875 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1876
16618
6bae941b58ad parsers: change the type of nt_level
Bryan O'Sullivan <bryano@fb.com>
parents: 16617
diff changeset
1877 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
1878 {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1879 int v = node[level >> 1];
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1880 if (!(level & 1))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1881 v >>= 4;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1882 return v & 0xf;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1883 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1884
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1885 /*
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1886 * Return values:
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1887 *
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1888 * -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
1889 * -2: not found
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1890 * rest: valid rev
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1891 */
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1892 static int nt_find(nodetree *self, const char *node, Py_ssize_t nodelen,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1893 int hex)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1894 {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1895 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
1896 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
1897
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1898 /* If the input is binary, do a fast check for the nullid first. */
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1899 if (!hex && nodelen == self->nodelen && node[0] == '\0' &&
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1900 node[1] == '\0' && memcmp(node, nullid, self->nodelen) == 0)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1901 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1902
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1903 if (hex)
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1904 maxlevel = nodelen;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1905 else
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1906 maxlevel = 2 * nodelen;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1907 if (maxlevel > 2 * self->nodelen)
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1908 maxlevel = 2 * self->nodelen;
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
1909
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
1910 for (level = off = 0; level < maxlevel; level++) {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1911 int k = getnybble(node, level);
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1912 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
1913 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
1914
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1915 if (v < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1916 const char *n;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1917 Py_ssize_t i;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1918
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
1919 v = -(v + 2);
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1920 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
1921 if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1922 return -2;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1923 for (i = level; i < maxlevel; i++)
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1924 if (getnybble(node, i) != nt_level(n, i))
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1925 return -2;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
1926 return v;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1927 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1928 if (v == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1929 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1930 off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1931 }
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
1932 /* 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
1933 return -4;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1934 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1935
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
1936 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
1937 {
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
1938 if (self->length == self->capacity) {
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
1939 size_t newcapacity;
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
1940 nodetreenode *newnodes;
39071
06ff7ea4f440 index: avoid duplicating capacity-growth expression
Martin von Zweigbergk <martinvonz@google.com>
parents: 39070
diff changeset
1941 newcapacity = self->capacity * 2;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
1942 if (newcapacity >= SIZE_MAX / sizeof(nodetreenode)) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1943 PyErr_SetString(PyExc_MemoryError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1944 "overflow in nt_new");
24623
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
1945 return -1;
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
1946 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1947 newnodes =
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1948 realloc(self->nodes, newcapacity * sizeof(nodetreenode));
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
1949 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
1950 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
1951 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1952 }
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
1953 self->capacity = newcapacity;
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
1954 self->nodes = newnodes;
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
1955 memset(&self->nodes[self->length], 0,
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
1956 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
1957 }
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
1958 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
1959 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1960
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1961 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
1962 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1963 int level = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1964 int off = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1965
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1966 while (level < 2 * self->nodelen) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1967 int k = nt_level(node, level);
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
1968 nodetreenode *n;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1969 int v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1970
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1971 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
1972 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
1973
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1974 if (v == 0) {
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
1975 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
1976 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1977 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1978 if (v < 0) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1979 const char *oldnode =
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1980 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
1981 int noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1982
37999
514605777244 revlog: handle errors from index_node() in nt_insert() and index_slice_del()
Martin von Zweigbergk <martinvonz@google.com>
parents: 37978
diff changeset
1983 if (oldnode == NULL)
514605777244 revlog: handle errors from index_node() in nt_insert() and index_slice_del()
Martin von Zweigbergk <martinvonz@google.com>
parents: 37978
diff changeset
1984 return -1;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
1985 if (!memcmp(oldnode, node, self->nodelen)) {
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
1986 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
1987 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1988 }
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1989 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
1990 if (noff == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
1991 return -1;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1992 /* self->nodes may have been changed by realloc */
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1993 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
1994 off = noff;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1995 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
1996 n->children[nt_level(oldnode, ++level)] = v;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1997 if (level > self->depth)
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1998 self->depth = level;
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
1999 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
2000 } else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2001 level += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2002 off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2003 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2004 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2005
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2006 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2007 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2008
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2009 static PyObject *ntobj_insert(nodetreeObject *self, PyObject *args)
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2010 {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2011 Py_ssize_t rev;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2012 const char *node;
39227
42cc76d0f836 cext: fix revlog compiler error on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39226
diff changeset
2013 Py_ssize_t length;
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2014 if (!PyArg_ParseTuple(args, "n", &rev))
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2015 return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2016 length = index_length(self->nt.index);
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2017 if (rev < 0 || rev >= length) {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2018 PyErr_SetString(PyExc_ValueError, "revlog index out of range");
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2019 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2020 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2021 node = index_node_existing(self->nt.index, rev);
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2022 if (nt_insert(&self->nt, node, (int)rev) == -1)
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2023 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2024 Py_RETURN_NONE;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2025 }
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2026
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2027 static int nt_delete_node(nodetree *self, const char *node)
38845
f9fc59ea3135 index: create function for deleting node from nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38821
diff changeset
2028 {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2029 /* rev==-2 happens to get encoded as 0, which is interpreted as not set
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2030 */
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
2031 return nt_insert(self, node, -2);
38845
f9fc59ea3135 index: create function for deleting node from nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38821
diff changeset
2032 }
f9fc59ea3135 index: create function for deleting node from nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38821
diff changeset
2033
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2034 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: 38940
diff changeset
2035 {
39225
fcaffbd7e635 index: fix a comment about overflow-checking
Martin von Zweigbergk <martinvonz@google.com>
parents: 39219
diff changeset
2036 /* Initialize before overflow-checking to avoid nt_dealloc() crash. */
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2037 self->nodes = NULL;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2038
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2039 self->index = index;
39072
34eb999e29bf index: make capacity argument to nt_init be measured in revisions
Martin von Zweigbergk <martinvonz@google.com>
parents: 39071
diff changeset
2040 /* 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: 39071
diff changeset
2041 * terms of nodetree nodes. */
34eb999e29bf index: make capacity argument to nt_init be measured in revisions
Martin von Zweigbergk <martinvonz@google.com>
parents: 39071
diff changeset
2042 self->capacity = (capacity < 4 ? 4 : capacity / 2);
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2043 self->nodelen = index->nodelen;
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2044 self->depth = 0;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2045 self->splits = 0;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
2046 if (self->capacity > SIZE_MAX / sizeof(nodetreenode)) {
39070
4dd92a15fcca index: move check for too large capacity into nt_init()
Martin von Zweigbergk <martinvonz@google.com>
parents: 39069
diff changeset
2047 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: 39069
diff changeset
2048 return -1;
4dd92a15fcca index: move check for too large capacity into nt_init()
Martin von Zweigbergk <martinvonz@google.com>
parents: 39069
diff changeset
2049 }
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2050 self->nodes = calloc(self->capacity, sizeof(nodetreenode));
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2051 if (self->nodes == NULL) {
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2052 PyErr_NoMemory();
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2053 return -1;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2054 }
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2055 self->length = 1;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2056 return 0;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2057 }
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2058
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2059 static int ntobj_init(nodetreeObject *self, PyObject *args)
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2060 {
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2061 PyObject *index;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2062 unsigned capacity;
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
2063 if (!PyArg_ParseTuple(args, "O!I", &HgRevlogIndex_Type, &index,
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
2064 &capacity))
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2065 return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2066 Py_INCREF(index);
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2067 return nt_init(&self->nt, (indexObject *)index, capacity);
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2068 }
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2069
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2070 static int nt_partialmatch(nodetree *self, const char *node, Py_ssize_t nodelen)
38943
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2071 {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2072 return nt_find(self, node, nodelen, 1);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2073 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2074
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2075 /*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2076 * 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: 38942
diff changeset
2077 *
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2078 * Return values:
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2079 *
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2080 * -3: error (exception set)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2081 * -2: not found (no exception set)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2082 * rest: length of shortest prefix
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2083 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2084 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: 38942
diff changeset
2085 {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2086 int level, off;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2087
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2088 for (level = off = 0; level < 2 * self->nodelen; level++) {
38943
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2089 int k, v;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2090 nodetreenode *n = &self->nodes[off];
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2091 k = nt_level(node, level);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2092 v = n->children[k];
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2093 if (v < 0) {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2094 const char *n;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2095 v = -(v + 2);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2096 n = index_node_existing(self->index, v);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2097 if (n == NULL)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2098 return -3;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2099 if (memcmp(node, n, self->nodelen) != 0)
38943
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2100 /*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2101 * 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: 38942
diff changeset
2102 * requested node (i.e the requested node does
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2103 * not exist).
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2104 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2105 return -2;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2106 return level + 1;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2107 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2108 if (v == 0)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2109 return -2;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2110 off = v;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2111 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2112 /*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2113 * 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: 38942
diff changeset
2114 * 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: 38942
diff changeset
2115 * 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: 38942
diff changeset
2116 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2117 PyErr_SetString(PyExc_Exception, "broken node tree");
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2118 return -3;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2119 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2120
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2121 static PyObject *ntobj_shortest(nodetreeObject *self, PyObject *args)
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2122 {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2123 PyObject *val;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2124 char *node;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2125 int length;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2126
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2127 if (!PyArg_ParseTuple(args, "O", &val))
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2128 return NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2129 if (node_check(self->nt.nodelen, val, &node) == -1)
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2130 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2131
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2132 length = nt_shortest(&self->nt, node);
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2133 if (length == -3)
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2134 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2135 if (length == -2) {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2136 raise_revlog_error();
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2137 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2138 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2139 return PyLong_FromLong(length);
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2140 }
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2141
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2142 static void nt_dealloc(nodetree *self)
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2143 {
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2144 free(self->nodes);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2145 self->nodes = NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2146 }
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2147
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2148 static void ntobj_dealloc(nodetreeObject *self)
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2149 {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2150 Py_XDECREF(self->nt.index);
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2151 nt_dealloc(&self->nt);
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2152 PyObject_Del(self);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2153 }
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2154
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2155 static PyMethodDef ntobj_methods[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2156 {"insert", (PyCFunction)ntobj_insert, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2157 "insert an index entry"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2158 {"shortest", (PyCFunction)ntobj_shortest, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2159 "find length of shortest hex nodeid of a binary ID"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2160 {NULL} /* Sentinel */
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2161 };
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2162
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2163 static PyTypeObject nodetreeType = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2164 PyVarObject_HEAD_INIT(NULL, 0) /* header */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2165 "parsers.nodetree", /* tp_name */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2166 sizeof(nodetreeObject), /* tp_basicsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2167 0, /* tp_itemsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2168 (destructor)ntobj_dealloc, /* tp_dealloc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2169 0, /* tp_print */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2170 0, /* tp_getattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2171 0, /* tp_setattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2172 0, /* tp_compare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2173 0, /* tp_repr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2174 0, /* tp_as_number */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2175 0, /* tp_as_sequence */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2176 0, /* tp_as_mapping */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2177 0, /* tp_hash */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2178 0, /* tp_call */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2179 0, /* tp_str */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2180 0, /* tp_getattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2181 0, /* tp_setattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2182 0, /* tp_as_buffer */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2183 Py_TPFLAGS_DEFAULT, /* tp_flags */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2184 "nodetree", /* tp_doc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2185 0, /* tp_traverse */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2186 0, /* tp_clear */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2187 0, /* tp_richcompare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2188 0, /* tp_weaklistoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2189 0, /* tp_iter */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2190 0, /* tp_iternext */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2191 ntobj_methods, /* tp_methods */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2192 0, /* tp_members */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2193 0, /* tp_getset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2194 0, /* tp_base */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2195 0, /* tp_dict */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2196 0, /* tp_descr_get */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2197 0, /* tp_descr_set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2198 0, /* tp_dictoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2199 (initproc)ntobj_init, /* tp_init */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2200 0, /* tp_alloc */
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2201 };
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2202
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2203 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
2204 {
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2205 if (!self->ntinitialized) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2206 if (nt_init(&self->nt, self, (int)self->length) == -1) {
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2207 nt_dealloc(&self->nt);
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
2208 return -1;
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
2209 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2210 if (nt_insert(&self->nt, nullid, -1) == -1) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2211 nt_dealloc(&self->nt);
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2212 return -1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2213 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2214 self->ntinitialized = 1;
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
2215 self->ntrev = (int)index_length(self);
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2216 self->ntlookups = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2217 self->ntmisses = 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2218 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2219 return 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2220 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2221
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2222 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2223 * Return values:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2224 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2225 * -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
2226 * -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
2227 * rest: valid rev
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2228 */
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2229 static int index_find_node(indexObject *self, const char *node)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2230 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2231 int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2232
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2233 if (index_init_nt(self) == -1)
38820
44bbc89ec5e0 revlog: remove micro-optimization for looking up only nullid
Martin von Zweigbergk <martinvonz@google.com>
parents: 38819
diff changeset
2234 return -3;
44bbc89ec5e0 revlog: remove micro-optimization for looking up only nullid
Martin von Zweigbergk <martinvonz@google.com>
parents: 38819
diff changeset
2235
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2236 self->ntlookups++;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2237 rev = nt_find(&self->nt, node, self->nodelen, 0);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2238 if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2239 return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2240
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2241 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2242 * 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
2243 * 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
2244 * 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
2245 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2246 * 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
2247 * 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
2248 * 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
2249 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2250 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
2251 for (rev = self->ntrev - 1; rev >= 0; rev--) {
37861
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
2252 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
2253 if (n == NULL)
37861
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
2254 return -3;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2255 if (memcmp(node, n, self->nodelen) == 0) {
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2256 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
2257 return -3;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2258 break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2259 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2260 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2261 } else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2262 for (rev = self->ntrev - 1; rev >= 0; rev--) {
37861
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
2263 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: 37860
diff changeset
2264 if (n == NULL)
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
2265 return -3;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2266 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
2267 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
2268 return -3;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
2269 }
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2270 if (memcmp(node, n, self->nodelen) == 0) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2271 break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2272 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2273 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2274 self->ntrev = rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2275 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2276
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2277 if (rev >= 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2278 return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2279 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2280 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2281
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2282 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
2283 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2284 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2285 int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2286
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2287 if (PyLong_Check(value)) {
40598
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2288 long idx;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2289 if (!pylong_to_long(value, &idx)) {
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2290 return NULL;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2291 }
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2292 return index_get(self, idx);
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2293 }
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2294
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2295 if (node_check(self->nodelen, 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
2296 return NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2297 rev = index_find_node(self, node);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2298 if (rev >= -1)
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2299 return PyLong_FromLong(rev);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2300 if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2301 raise_revlog_error();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2302 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2303 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2304
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2305 /*
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2306 * Fully populate the radix tree.
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2307 */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2308 static int index_populate_nt(indexObject *self)
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2309 {
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2310 int rev;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2311 if (self->ntrev > 0) {
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2312 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: 37861
diff changeset
2313 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: 37861
diff changeset
2314 if (n == NULL)
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2315 return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2316 if (nt_insert(&self->nt, n, rev) == -1)
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2317 return -1;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2318 }
37930
892592475094 revlog: use literal -1 instead of variable that always has that value
Martin von Zweigbergk <martinvonz@google.com>
parents: 37929
diff changeset
2319 self->ntrev = -1;
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2320 }
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2321 return 0;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2322 }
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2323
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2324 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
2325 {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2326 const char *fullnode;
42067
b01bbb8ff1f2 cext: make revlog.c PY_SSIZE_T_CLEAN
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41283
diff changeset
2327 Py_ssize_t nodelen;
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2328 char *node;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2329 int rev, i;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2330
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
2331 if (!PyArg_ParseTuple(args, "y#", &node, &nodelen))
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2332 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2333
37858
92ed344a9e64 revlog: use radix tree also for matching keys shorter than 4 hex digits
Martin von Zweigbergk <martinvonz@google.com>
parents: 36623
diff changeset
2334 if (nodelen < 1) {
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2335 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
2336 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2337 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2338
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2339 if (nodelen > 2 * self->nodelen) {
17353
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
2340 PyErr_SetString(PyExc_ValueError, "key too long");
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
2341 return NULL;
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
2342 }
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2343
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2344 for (i = 0; i < nodelen; i++)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2345 hexdigit(node, i);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2346 if (PyErr_Occurred()) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2347 /* input contains non-hex characters */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2348 PyErr_Clear();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2349 Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2350 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2351
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2352 if (index_init_nt(self) == -1)
38911
2aa4f06c1e91 index: make "nt_*" functions work on an initialized nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38868
diff changeset
2353 return NULL;
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
2354 if (index_populate_nt(self) == -1)
38911
2aa4f06c1e91 index: make "nt_*" functions work on an initialized nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38868
diff changeset
2355 return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2356 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
2357
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2358 switch (rev) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2359 case -4:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2360 raise_revlog_error();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2361 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2362 case -2:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2363 Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2364 case -1:
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2365 return PyBytes_FromStringAndSize(nullid, self->nodelen);
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2366 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2367
37860
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
2368 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
2369 if (fullnode == NULL) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2370 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2371 }
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2372 return PyBytes_FromStringAndSize(fullnode, self->nodelen);
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2373 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2374
37968
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2375 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: 37930
diff changeset
2376 {
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2377 PyObject *val;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2378 char *node;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2379 int length;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2380
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2381 if (!PyArg_ParseTuple(args, "O", &val))
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2382 return NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2383 if (node_check(self->nodelen, val, &node) == -1)
37968
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2384 return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2385
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2386 self->ntlookups++;
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2387 if (index_init_nt(self) == -1)
38911
2aa4f06c1e91 index: make "nt_*" functions work on an initialized nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38868
diff changeset
2388 return NULL;
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
2389 if (index_populate_nt(self) == -1)
38911
2aa4f06c1e91 index: make "nt_*" functions work on an initialized nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38868
diff changeset
2390 return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2391 length = nt_shortest(&self->nt, node);
37968
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2392 if (length == -3)
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2393 return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2394 if (length == -2) {
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2395 raise_revlog_error();
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2396 return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2397 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2398 return PyLong_FromLong(length);
37968
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2399 }
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2400
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2401 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
2402 {
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
2403 PyObject *val;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2404 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
2405 int rev;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2406
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
2407 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
2408 return NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2409 if (node_check(self->nodelen, 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
2410 return NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2411 rev = index_find_node(self, node);
27638
90e3c5129226 cleanup: remove superfluous space after space after equals (C)
timeless <timeless@mozdev.org>
parents: 27592
diff changeset
2412 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
2413 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2414 if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2415 Py_RETURN_NONE;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2416 return PyLong_FromLong(rev);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2417 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2418
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2419 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
2420 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2421 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2422
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2423 if (PyLong_Check(value)) {
40598
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2424 long rev;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2425 if (!pylong_to_long(value, &rev)) {
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2426 return -1;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2427 }
38866
aa33988ad8ab index: return False for "len(index) in index"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38852
diff changeset
2428 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
2429 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2430
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2431 if (node_check(self->nodelen, 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
2432 return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2433
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2434 switch (index_find_node(self, node)) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2435 case -3:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2436 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2437 case -2:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2438 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2439 default:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2440 return 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2441 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2442 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2443
43534
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2444 static PyObject *index_m_has_node(indexObject *self, PyObject *args)
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2445 {
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2446 int ret = index_contains(self, args);
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2447 if (ret < 0)
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2448 return NULL;
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2449 return PyBool_FromLong((long)ret);
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2450 }
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2451
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2452 static PyObject *index_m_rev(indexObject *self, PyObject *val)
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2453 {
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2454 char *node;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2455 int rev;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2456
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2457 if (node_check(self->nodelen, val, &node) == -1)
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2458 return NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2459 rev = index_find_node(self, node);
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2460 if (rev >= -1)
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2461 return PyLong_FromLong(rev);
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2462 if (rev == -2)
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2463 raise_revlog_error();
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2464 return NULL;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2465 }
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2466
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2467 typedef uint64_t bitmask;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2468
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2469 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2470 * 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
2471 * 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
2472 * "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
2473 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2474 static PyObject *find_gca_candidates(indexObject *self, const int *revs,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2475 int revcount)
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2476 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2477 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
2478 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
2479 PyObject *gca = PyList_New(0);
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2480 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
2481 int maxrev = -1;
22399
9f490afcb067 parsers: use bitmask type consistently in find_gca_candidates
Henrik Stuart <hg@hstuart.dk>
parents: 21871
diff changeset
2482 bitmask sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2483 bitmask *seen;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2484
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2485 if (gca == NULL)
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2486 return PyErr_NoMemory();
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2487
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2488 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
2489 if (revs[i] > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2490 maxrev = revs[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2491 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2492
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2493 seen = calloc(sizeof(*seen), maxrev + 1);
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2494 if (seen == NULL) {
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2495 Py_DECREF(gca);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2496 return PyErr_NoMemory();
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2497 }
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2498
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2499 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
2500 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
2501
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2502 interesting = revcount;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2503
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2504 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
2505 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
2506 int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2507
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2508 if (!sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2509 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2510
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2511 if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2512 interesting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2513 if (sv == allseen) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2514 PyObject *obj = PyLong_FromLong(v);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2515 if (obj == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2516 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2517 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
2518 Py_DECREF(obj);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2519 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2520 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2521 sv |= poison;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2522 for (i = 0; i < revcount; i++) {
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2523 if (revs[i] == v)
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2524 goto done;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2525 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2526 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2527 }
25810
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
2528 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
2529 goto bail;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2530
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2531 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
2532 int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2533 if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2534 continue;
19030
48d6f436363e parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents: 18988
diff changeset
2535 sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2536 if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2537 if (sp == 0) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2538 seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2539 interesting++;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2540 } else if (sp != sv)
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2541 seen[p] |= sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2542 } else {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2543 if (sp && sp < poison)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2544 interesting--;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2545 seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2546 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2547 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2548 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2549
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2550 done:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2551 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2552 return gca;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2553 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2554 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2555 Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2556 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2557 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2558
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2559 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2560 * 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
2561 * path to the root.
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2562 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2563 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
2564 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2565 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
2566 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
2567 int *depth, *interesting = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2568 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
2569 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
2570 long *seen = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2571 int maxrev = -1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2572 long final;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2573
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2574 if (revcount > capacity) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2575 PyErr_Format(PyExc_OverflowError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2576 "bitset size (%ld) > capacity (%ld)",
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2577 (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
2578 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2579 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2580
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2581 for (i = 0; i < revcount; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2582 int n = (int)PyLong_AsLong(PyList_GET_ITEM(revs, i));
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2583 if (n > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2584 maxrev = n;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2585 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2586
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2587 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
2588 if (depth == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2589 return PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2590
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2591 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
2592 if (seen == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2593 PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2594 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2595 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2596
39073
beab6690f202 cext: fix Windows warning about implicit conversion of 32-bit shift to 64 bit
Matt Harbison <matt_harbison@yahoo.com>
parents: 39072
diff changeset
2597 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
2598 if (interesting == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2599 PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2600 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2601 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2602
19502
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
2603 if (PyList_Sort(revs) == -1)
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
2604 goto bail;
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
2605
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2606 for (i = 0; i < revcount; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2607 int n = (int)PyLong_AsLong(PyList_GET_ITEM(revs, i));
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2608 long b = 1l << i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2609 depth[n] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2610 seen[n] = b;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2611 interesting[b] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2612 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2613
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2614 /* invariant: ninteresting is the number of non-zero entries in
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2615 * interesting. */
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2616 ninteresting = (int)revcount;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2617
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2618 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
2619 int dv = depth[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2620 int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2621 long sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2622
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2623 if (dv == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2624 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2625
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2626 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
2627 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
2628 goto bail;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2629
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2630 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
2631 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
2632 long sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2633 int dp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2634
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2635 if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2636 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2637
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2638 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
2639 sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2640 if (dp <= dv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2641 depth[p] = dv + 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2642 if (sp != sv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2643 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
2644 seen[p] = sv;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2645 if (sp) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2646 interesting[sp] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2647 if (interesting[sp] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2648 ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2649 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2650 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2651 } 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
2652 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
2653 if (nsp == sp)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2654 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2655 seen[p] = nsp;
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
2656 interesting[sp] -= 1;
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2657 if (interesting[sp] == 0)
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
2658 ninteresting -= 1;
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2659 if (interesting[nsp] == 0)
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2660 ninteresting += 1;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2661 interesting[nsp] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2662 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2663 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2664 interesting[sv] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2665 if (interesting[sv] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2666 ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2667 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2668
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2669 final = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2670 j = ninteresting;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2671 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
2672 if (interesting[i] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2673 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2674 final |= i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2675 j -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2676 }
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2677 if (final == 0) {
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2678 keys = PyList_New(0);
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2679 goto bail;
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2680 }
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2681
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2682 dict = PyDict_New();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2683 if (dict == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2684 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2685
19504
2fa303619b4d ancestor.deepest: ignore ninteresting while building result (issue3984)
Siddharth Agarwal <sid0@fb.com>
parents: 19503
diff changeset
2686 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
2687 PyObject *key;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2688
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2689 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
2690 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2691
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2692 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
2693 Py_INCREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2694 Py_INCREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2695 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
2696 Py_DECREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2697 Py_DECREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2698 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2699 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2700 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2701
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2702 keys = PyDict_Keys(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2703
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2704 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2705 free(depth);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2706 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2707 free(interesting);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2708 Py_XDECREF(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2709
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2710 return keys;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2711 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2712
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2713 /*
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2714 * Given a (possibly overlapping) set of revs, return all the
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2715 * common ancestors heads: heads(::args[0] and ::a[1] and ...)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2716 */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2717 static PyObject *index_commonancestorsheads(indexObject *self, PyObject *args)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2718 {
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
2719 PyObject *ret = NULL;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2720 Py_ssize_t argcount, i, len;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2721 bitmask repeat = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2722 int revcount = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2723 int *revs;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2724
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2725 argcount = PySequence_Length(args);
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
2726 revs = PyMem_Malloc(argcount * sizeof(*revs));
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2727 if (argcount > 0 && revs == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2728 return PyErr_NoMemory();
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
2729 len = index_length(self);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2730
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2731 for (i = 0; i < argcount; i++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2732 static const int capacity = 24;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2733 PyObject *obj = PySequence_GetItem(args, i);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2734 bitmask x;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2735 long val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2736
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2737 if (!PyLong_Check(obj)) {
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2738 PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2739 "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
2740 Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2741 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2742 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2743 val = PyLong_AsLong(obj);
23945
33d6aaf84c9e parsers.c: fix a memory leak in index_commonancestorsheads
Augie Fackler <augie@google.com>
parents: 23944
diff changeset
2744 Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2745 if (val == -1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2746 ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2747 goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2748 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2749 if (val < 0 || val >= len) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2750 PyErr_SetString(PyExc_IndexError, "index out of range");
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2751 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2752 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2753 /* this cheesy bloom filter lets us avoid some more
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2754 * expensive duplicate checks in the common set-is-disjoint
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2755 * case */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2756 x = 1ull << (val & 0x3f);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2757 if (repeat & x) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2758 int k;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2759 for (k = 0; k < revcount; k++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2760 if (val == revs[k])
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2761 goto duplicate;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2762 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2763 } else
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2764 repeat |= x;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2765 if (revcount >= capacity) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2766 PyErr_Format(PyExc_OverflowError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2767 "bitset size (%d) > capacity (%d)",
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2768 revcount, capacity);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2769 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2770 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2771 revs[revcount++] = (int)val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2772 duplicate:;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2773 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2774
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2775 if (revcount == 0) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2776 ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2777 goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2778 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2779 if (revcount == 1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2780 PyObject *obj;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2781 ret = PyList_New(1);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2782 if (ret == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2783 goto bail;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2784 obj = PyLong_FromLong(revs[0]);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2785 if (obj == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2786 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2787 PyList_SET_ITEM(ret, 0, obj);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2788 goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2789 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2790
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
2791 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
2792 if (ret == NULL)
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2793 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2794
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2795 done:
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
2796 PyMem_Free(revs);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2797 return ret;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2798
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2799 bail:
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
2800 PyMem_Free(revs);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2801 Py_XDECREF(ret);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2802 return NULL;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2803 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2804
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2805 /*
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2806 * 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
2807 * 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
2808 */
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2809 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
2810 {
26048
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
2811 PyObject *ret;
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2812 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
2813 if (gca == NULL)
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2814 return NULL;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2815
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2816 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
2817 return gca;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2818 }
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2819
26048
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
2820 ret = find_deepest(self, gca);
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
2821 Py_DECREF(gca);
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
2822 return ret;
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2823 }
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2824
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
2825 /*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2826 * 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
2827 */
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
2828 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
2829 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2830 Py_ssize_t i, len;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2831
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2832 len = self->length + self->new_length;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2833 i = start - self->length;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2834 if (i < 0)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2835 return;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2836
48766
d9a7131648a3 revlog: do not compute node location by hand in index_invalidate_added
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48722
diff changeset
2837 for (i = start; i < len; i++) {
d9a7131648a3 revlog: do not compute node location by hand in index_invalidate_added
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48722
diff changeset
2838 const char *node = index_node(self, i);
d9a7131648a3 revlog: do not compute node location by hand in index_invalidate_added
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48722
diff changeset
2839 nt_delete_node(&self->nt, node);
d9a7131648a3 revlog: do not compute node location by hand in index_invalidate_added
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48722
diff changeset
2840 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2841
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2842 self->new_length = 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
2843 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2844
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2845 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2846 * Delete a numeric range of revs, which must be at the end of the
43582
ae5e39512ca0 revlog: delete references to deleted nullid sentinel value
Martin von Zweigbergk <martinvonz@google.com>
parents: 43554
diff changeset
2847 * range.
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2848 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2849 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
2850 {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2851 Py_ssize_t start, stop, step, slicelength;
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
2852 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
2853 int ret = 0;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2854
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2855 if (PySlice_GetIndicesEx(item, length, &start, &stop, &step,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2856 &slicelength) < 0)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2857 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2858
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2859 if (slicelength <= 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2860 return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2861
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2862 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
2863 stop = start;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
2864
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2865 if (step < 0) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2866 stop = start + 1;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2867 start = stop + step * (slicelength - 1) - 1;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2868 step = -step;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2869 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2870
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2871 if (step != 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2872 PyErr_SetString(PyExc_ValueError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2873 "revlog index delete requires step size of 1");
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2874 return -1;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
2875 }
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2876
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2877 if (stop != length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2878 PyErr_SetString(PyExc_IndexError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2879 "revlog index deletion indices are invalid");
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2880 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2881 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2882
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
2883 if (start < self->length) {
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2884 if (self->ntinitialized) {
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2885 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
2886
43532
53581e220ba3 revlog: clean up the node of all revision stripped in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42096
diff changeset
2887 for (i = start; i < self->length; i++) {
37999
514605777244 revlog: handle errors from index_node() in nt_insert() and index_slice_del()
Martin von Zweigbergk <martinvonz@google.com>
parents: 37978
diff changeset
2888 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: 37978
diff changeset
2889 if (node == NULL)
514605777244 revlog: handle errors from index_node() in nt_insert() and index_slice_del()
Martin von Zweigbergk <martinvonz@google.com>
parents: 37978
diff changeset
2890 return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2891
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2892 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
2893 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2894 if (self->new_length)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2895 index_invalidate_added(self, self->length);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2896 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
2897 self->ntrev = (int)start;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2898 } else if (self->new_length) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2899 self->new_length = 0;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2900 }
43847
49fa0b31ee1d cext-revlog: fixed __delitem__ for uninitialized nodetree
Georges Racinet <georges.racinet@octobus.net>
parents: 43582
diff changeset
2901
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
2902 self->length = start;
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
2903 goto done;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
2904 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
2905
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2906 if (self->ntinitialized) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2907 index_invalidate_added(self, start);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2908 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
2909 self->ntrev = (int)start;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2910 } else {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2911 self->new_length = 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
2912 }
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
2913 done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
2914 Py_CLEAR(self->headrevs);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
2915 return ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2916 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2917
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2918 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2919 * Supported ops:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2920 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2921 * slice deletion
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2922 * 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
2923 * 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
2924 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2925 static int index_assign_subscript(indexObject *self, PyObject *item,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2926 PyObject *value)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2927 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2928 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2929 long rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2930
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2931 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
2932 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
2933
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2934 if (node_check(self->nodelen, 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
2935 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2936
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2937 if (value == NULL)
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2938 return self->ntinitialized ? nt_delete_node(&self->nt, node)
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2939 : 0;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2940 rev = PyLong_AsLong(value);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2941 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
2942 if (!PyErr_Occurred())
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2943 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
2944 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2945 }
23468
ee311681e591 parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents: 23087
diff changeset
2946
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2947 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
2948 return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2949 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
2950 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2951
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2952 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2953 * 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
2954 * 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
2955 */
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
2956 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
2957 {
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
2958 const char *data = (const char *)self->buf.buf;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
2959 Py_ssize_t pos = 0;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
2960 Py_ssize_t end = self->buf.len;
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
2961 long incr = self->entry_size;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2962 Py_ssize_t len = 0;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
2963
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
2964 while (pos + self->entry_size <= end && pos >= 0) {
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
2965 uint32_t comp_len, sidedata_comp_len = 0;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2966 /* 3rd element of header is length of compressed inline data */
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2967 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2968 comp_len =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2969 getbe32(data + pos + entry_v1_offset_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2970 sidedata_comp_len = 0;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2971 } else if (self->format_version == format_v2) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2972 comp_len =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2973 getbe32(data + pos + entry_v2_offset_comp_len);
48721
a9364de9be29 revlog: extract entry byte offsets into named constants
pacien <pacien.trangirard@pacien.net>
parents: 48499
diff changeset
2974 sidedata_comp_len = getbe32(
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2975 data + pos + entry_v2_offset_sidedata_comp_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2976 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2977 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
2978 return -1;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
2979 }
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
2980 incr = self->entry_size + comp_len + sidedata_comp_len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2981 if (offsets)
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
2982 offsets[len] = data + pos;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2983 len++;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
2984 pos += incr;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2985 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
2986
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
2987 if (pos != end) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2988 if (!PyErr_Occurred())
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2989 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
2990 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2991 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2992
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2993 return len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2994 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
2995
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
2996 static int index_init(indexObject *self, PyObject *args, PyObject *kwargs)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
2997 {
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
2998 PyObject *data_obj, *inlined_obj;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
2999 Py_ssize_t size;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3000
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3001 static char *kwlist[] = {"data", "inlined", "format", NULL};
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3002
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3003 /* Initialize before argument-checking to avoid index_dealloc() crash.
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3004 */
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3005 self->added = NULL;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3006 self->new_length = 0;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3007 self->added_length = 0;
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3008 self->data = NULL;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3009 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
3010 self->headrevs = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
3011 self->filteredrevs = Py_None;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
3012 Py_INCREF(Py_None);
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3013 self->ntinitialized = 0;
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3014 self->offsets = NULL;
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3015 self->nodelen = 20;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3016 self->nullentry = NULL;
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47259
diff changeset
3017 self->rust_ext_compat = 1;
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3018 self->format_version = format_v1;
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3019
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3020 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|l", kwlist,
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3021 &data_obj, &inlined_obj,
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3022 &(self->format_version)))
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3023 return -1;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3024 if (!PyObject_CheckBuffer(data_obj)) {
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3025 PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3026 "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
3027 return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3028 }
46144
e4f6dae01b3b cext: shut-up sign compare warnings
Joerg Sonnenberger <joerg@bec.de>
parents: 46141
diff changeset
3029 if (self->nodelen < 20 || self->nodelen > (Py_ssize_t)sizeof(nullid)) {
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3030 PyErr_SetString(PyExc_RuntimeError, "unsupported node size");
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3031 return -1;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3032 }
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3033
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3034 if (self->format_version == format_v1) {
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3035 self->entry_size = v1_entry_size;
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3036 } else if (self->format_version == format_v2) {
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3037 self->entry_size = v2_entry_size;
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3038 } else if (self->format_version == format_cl2) {
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3039 self->entry_size = cl2_entry_size;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3040 }
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3041
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
3042 self->nullentry = Py_BuildValue(
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
3043 "iiiiiiiy#iiBBi", 0, 0, 0, -1, -1, -1, -1, nullid, self->nodelen, 0,
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
3044 0, comp_mode_inline, comp_mode_inline, rank_unknown);
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3045
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3046 if (!self->nullentry)
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3047 return -1;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3048 PyObject_GC_UnTrack(self->nullentry);
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3049
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3050 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
3051 return -1;
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3052 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
3053
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3054 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
3055 self->data = data_obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3056
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3057 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
3058 self->ntrev = -1;
16597
b767382a8675 parsers: fix refcount bug on corrupt index
Matt Mackall <mpm@selenic.com>
parents: 16572
diff changeset
3059 Py_INCREF(self->data);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3060
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3061 if (self->inlined) {
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
3062 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
3063 if (len == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3064 goto bail;
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
3065 self->length = len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3066 } else {
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3067 if (size % self->entry_size) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3068 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
3069 goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3070 }
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3071 self->length = size / self->entry_size;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3072 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3073
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3074 return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3075 bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3076 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3077 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3078
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3079 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
3080 {
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3081 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
3082 return (PyObject *)self;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3083 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3084
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3085 static void _index_clearcaches(indexObject *self)
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3086 {
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3087 if (self->offsets) {
39075
b935adb4b041 cext: fix a warning about differing const qualifiers on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39074
diff changeset
3088 PyMem_Free((void *)self->offsets);
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3089 self->offsets = NULL;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3090 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3091 if (self->ntinitialized) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3092 nt_dealloc(&self->nt);
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3093 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3094 self->ntinitialized = 0;
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3095 Py_CLEAR(self->headrevs);
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3096 }
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3097
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3098 static PyObject *index_clearcaches(indexObject *self)
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3099 {
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3100 _index_clearcaches(self);
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3101 self->ntrev = -1;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3102 self->ntlookups = self->ntmisses = 0;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3103 Py_RETURN_NONE;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3104 }
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3105
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3106 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
3107 {
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
3108 _index_clearcaches(self);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
3109 Py_XDECREF(self->filteredrevs);
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3110 if (self->buf.buf) {
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3111 PyBuffer_Release(&self->buf);
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3112 memset(&self->buf, 0, sizeof(self->buf));
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3113 }
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3114 Py_XDECREF(self->data);
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3115 PyMem_Free(self->added);
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3116 Py_XDECREF(self->nullentry);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3117 PyObject_Del(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3118 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3119
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3120 static PySequenceMethods index_sequence_methods = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3121 (lenfunc)index_length, /* sq_length */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3122 0, /* sq_concat */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3123 0, /* sq_repeat */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3124 (ssizeargfunc)index_get, /* sq_item */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3125 0, /* sq_slice */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3126 0, /* sq_ass_item */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3127 0, /* sq_ass_slice */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3128 (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
3129 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3130
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3131 static PyMappingMethods index_mapping_methods = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3132 (lenfunc)index_length, /* mp_length */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3133 (binaryfunc)index_getitem, /* mp_subscript */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3134 (objobjargproc)index_assign_subscript, /* mp_ass_subscript */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3135 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3136
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3137 static PyMethodDef index_methods[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3138 {"ancestors", (PyCFunction)index_ancestors, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3139 "return the gca set of the given revs"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3140 {"commonancestorsheads", (PyCFunction)index_commonancestorsheads,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3141 METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3142 "return the heads of the common ancestors of the given revs"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3143 {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3144 "clear the index caches"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3145 {"get", (PyCFunction)index_m_get, METH_VARARGS, "get an index entry"},
43554
b56de57c45ce index: add a `get_rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43552
diff changeset
3146 {"get_rev", (PyCFunction)index_m_get, METH_VARARGS,
b56de57c45ce index: add a `get_rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43552
diff changeset
3147 "return `rev` associated with a node or None"},
43534
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
3148 {"has_node", (PyCFunction)index_m_has_node, METH_O,
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
3149 "return True if the node exist in the index"},
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
3150 {"rev", (PyCFunction)index_m_rev, METH_O,
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
3151 "return `rev` associated with a node or raise RevlogError"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3152 {"computephasesmapsets", (PyCFunction)compute_phases_map_sets, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3153 "compute phases"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3154 {"reachableroots2", (PyCFunction)reachableroots2, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3155 "reachableroots"},
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
3156 {"replace_sidedata_info", (PyCFunction)index_replace_sidedata_info,
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
3157 METH_VARARGS, "replace an existing index entry with a new value"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3158 {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3159 "get head revisions"}, /* Can do filtering since 3.2 */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3160 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3161 "get filtered head revisions"}, /* Can always do filtering */
41086
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
3162 {"issnapshot", (PyCFunction)index_issnapshot, METH_O,
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
3163 "True if the object is a snapshot"},
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
3164 {"findsnapshots", (PyCFunction)index_findsnapshots, METH_VARARGS,
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
3165 "Gather snapshot data in a cache dict"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3166 {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3167 "determine revisions with deltas to reconstruct fulltext"},
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
3168 {"slicechunktodensity", (PyCFunction)index_slicechunktodensity,
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
3169 METH_VARARGS, "determine revisions with deltas to reconstruct fulltext"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3170 {"append", (PyCFunction)index_append, METH_O, "append an index entry"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3171 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3172 "match a potentially ambiguous node ID"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3173 {"shortest", (PyCFunction)index_shortest, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3174 "find length of shortest hex nodeid of a binary ID"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3175 {"stats", (PyCFunction)index_stats, METH_NOARGS, "stats for the index"},
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
3176 {"entry_binary", (PyCFunction)index_entry_binary, METH_O,
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
3177 "return an entry in binary form"},
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
3178 {"pack_header", (PyCFunction)index_pack_header, METH_VARARGS,
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47035
diff changeset
3179 "pack the revlog header information into binary"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3180 {NULL} /* Sentinel */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3181 };
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3182
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3183 static PyGetSetDef index_getset[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3184 {"nodemap", (getter)index_nodemap, NULL, "nodemap", NULL},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3185 {NULL} /* Sentinel */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3186 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3187
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3188 static PyMemberDef index_members[] = {
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3189 {"entry_size", T_LONG, offsetof(indexObject, entry_size), 0,
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3190 "size of an index entry"},
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47259
diff changeset
3191 {"rust_ext_compat", T_LONG, offsetof(indexObject, rust_ext_compat), 0,
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3192 "size of an index entry"},
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3193 {NULL} /* Sentinel */
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3194 };
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3195
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3196 PyTypeObject HgRevlogIndex_Type = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3197 PyVarObject_HEAD_INIT(NULL, 0) /* header */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3198 "parsers.index", /* tp_name */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3199 sizeof(indexObject), /* tp_basicsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3200 0, /* tp_itemsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3201 (destructor)index_dealloc, /* tp_dealloc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3202 0, /* tp_print */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3203 0, /* tp_getattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3204 0, /* tp_setattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3205 0, /* tp_compare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3206 0, /* tp_repr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3207 0, /* tp_as_number */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3208 &index_sequence_methods, /* tp_as_sequence */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3209 &index_mapping_methods, /* tp_as_mapping */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3210 0, /* tp_hash */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3211 0, /* tp_call */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3212 0, /* tp_str */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3213 0, /* tp_getattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3214 0, /* tp_setattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3215 0, /* tp_as_buffer */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3216 Py_TPFLAGS_DEFAULT, /* tp_flags */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3217 "revlog index", /* tp_doc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3218 0, /* tp_traverse */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3219 0, /* tp_clear */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3220 0, /* tp_richcompare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3221 0, /* tp_weaklistoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3222 0, /* tp_iter */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3223 0, /* tp_iternext */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3224 index_methods, /* tp_methods */
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46875
diff changeset
3225 index_members, /* tp_members */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3226 index_getset, /* tp_getset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3227 0, /* tp_base */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3228 0, /* tp_dict */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3229 0, /* tp_descr_get */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3230 0, /* tp_descr_set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3231 0, /* tp_dictoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3232 (initproc)index_init, /* tp_init */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3233 0, /* tp_alloc */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3234 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3235
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3236 /*
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3237 * returns a tuple of the form (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
3238 * follows:
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3239 *
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3240 * index: an index object that lazily parses Revlog (v1 or v2) records
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3241 * 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
3242 * 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
3243 *
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3244 * added complications are for backwards compatibility
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3245 */
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3246 PyObject *parse_index2(PyObject *self, PyObject *args, PyObject *kwargs)
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3247 {
45173
2bc5d1531235 revlog: fix excessive decref on tuple creation failure in parse_index2()
Yuya Nishihara <yuya@tcha.org>
parents: 45141
diff changeset
3248 PyObject *cache = NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3249 indexObject *idx;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3250 int ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3251
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3252 idx = PyObject_New(indexObject, &HgRevlogIndex_Type);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3253 if (idx == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3254 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3255
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3256 ret = index_init(idx, args, kwargs);
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3257 if (ret == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3258 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3259
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3260 if (idx->inlined) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3261 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
3262 if (cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3263 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3264 } else {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3265 cache = Py_None;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3266 Py_INCREF(cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3267 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3268
45173
2bc5d1531235 revlog: fix excessive decref on tuple creation failure in parse_index2()
Yuya Nishihara <yuya@tcha.org>
parents: 45141
diff changeset
3269 return Py_BuildValue("NN", idx, cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3270
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3271 bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3272 Py_XDECREF(idx);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3273 Py_XDECREF(cache);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3274 return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3275 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3276
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3277 static Revlog_CAPI CAPI = {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
3278 /* increment the abi_version field upon each change in the Revlog_CAPI
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
3279 struct or in the ABI of the listed functions */
48852
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
3280 3, index_length, index_node, index_fast_rank, HgRevlogIndex_GetParents,
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3281 };
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3282
32378
7d0c69505a66 cext: extract revlog/index parsing code to own C file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32372
diff changeset
3283 void revlog_module_init(PyObject *mod)
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
3284 {
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents: 40963
diff changeset
3285 PyObject *caps = NULL;
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3286 HgRevlogIndex_Type.tp_new = PyType_GenericNew;
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3287 if (PyType_Ready(&HgRevlogIndex_Type) < 0)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3288 return;
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3289 Py_INCREF(&HgRevlogIndex_Type);
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3290 PyModule_AddObject(mod, "index", (PyObject *)&HgRevlogIndex_Type);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3291
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3292 nodetreeType.tp_new = PyType_GenericNew;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3293 if (PyType_Ready(&nodetreeType) < 0)
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3294 return;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3295 Py_INCREF(&nodetreeType);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3296 PyModule_AddObject(mod, "nodetree", (PyObject *)&nodetreeType);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3297
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3298 caps = PyCapsule_New(&CAPI, "mercurial.cext.parsers.revlog_CAPI", NULL);
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents: 40963
diff changeset
3299 if (caps != NULL)
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3300 PyModule_AddObject(mod, "revlog_CAPI", caps);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3301 }