annotate mercurial/cext/revlog.c @ 51396:3f37d80d3ab4

revlog: add a C implementation of `headrevsdiff` Python implementation of `headrevsdiff` can be very slow in the worst case compared with the `heads` computation it replaces, since the latter is done in C. Even the average case of this Python implementation is still noticeable in the profiles. This patch makes the computation much much faster by doing it in C.
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Thu, 21 Dec 2023 20:30:03 +0000
parents 3a7ef1398385
children f8bf1a8e9181
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;
48964
9ce563fb2989 revlog: fix wrong type of rank_unknown variable
Julien Cristau <jcristau@debian.org>
parents: 48769
diff changeset
171 static const int 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];
49212
d3d3495a5749 revlog: use appropriate format char for int ("i" instead of "I")
Anton Shestakov <av6@dwimlabs.net>
parents: 49211
diff changeset
494 if (!PyArg_ParseTuple(args, "i", &header)) {
47037
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 "
49211
675594a0a71a revlog: use %d to format int instead of %lu (issue6565)
Anton Shestakov <av6@dwimlabs.net>
parents: 48970
diff changeset
500 "index: %d",
47235
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
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
583 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
584 return rank_unknown;
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
585 }
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 if (pos == nullrev) {
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
588 return 0; /* convention */
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
589 }
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
590
48970
890db1c97218 revlog: fix index_fast_rank (wip)
Julien Cristau <jcristau@debian.org>
parents: 48965
diff changeset
591 return getbe32(index_deref(self, pos) + entry_cl2_offset_rank);
48852
e633e660158f revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents: 48821
diff changeset
592 }
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 /*
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
595 * 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
596 * 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
597 */
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
598 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
599 {
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
600 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
601 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
602 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
603 (int)pos);
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
604 }
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
605 return node;
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
606 }
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
607
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
608 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
609
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
610 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
611 {
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
612 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
613 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
614 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
615 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
616 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
617 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
618 thisnodelen, nodelen);
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
619 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
620 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
621
38850
6104b203bec8 index: replace insert(-1, e) method by append(e) method
Martin von Zweigbergk <martinvonz@google.com>
parents: 38848
diff changeset
622 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
623 {
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
624 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
625 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
626 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
627 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
628 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
629 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
630 char comp_field;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
631 char *data;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
632
47143
47ffc754989a revlog: always "append" full size tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47142
diff changeset
633 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
634 &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
635 &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
636 &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
637 &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
638 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
639 return NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
640 }
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
641
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
642 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
643 PyErr_SetString(PyExc_TypeError, "invalid node");
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
644 return NULL;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
645 }
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
646 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
647
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 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
649 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
650 "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
651 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
652 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
653 }
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 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
655 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
656 "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
657 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
658 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
659 }
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
660 }
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
661
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
662 if (self->new_length == self->added_length) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
663 size_t new_added_length =
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
664 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
665 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
666 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
667 if (!new_added)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
668 return PyErr_NoMemory();
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
669 self->added = new_added;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
670 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
671 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
672 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
673 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
674
48767
654baf1faa52 revlog: memset whole record instead of dealing with padding
pacien <pacien.trangirard@pacien.net>
parents: 48766
diff changeset
675 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
676
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
677 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
678 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
679 putbe32(offset_flags & 0xffffffffU,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
680 data + entry_v1_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
681 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
682 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
683 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
684 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
685 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
686 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
687 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
688 c_node_id_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
689 } 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
690 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
691 putbe32(offset_flags & 0xffffffffU,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
692 data + entry_v2_offset_offset_flags);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
693 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
694 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
695 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
696 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
697 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
698 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
699 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
700 c_node_id_len);
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
701 putbe64(sidedata_offset,
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
702 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
703 putbe32(sidedata_comp_len,
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
704 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
705 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
706 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
707 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
708 } 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
709 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
710 putbe32(offset_flags & 0xffffffffU,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
711 data + entry_cl2_offset_offset_flags);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
712 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
713 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
714 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
715 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
716 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
717 c_node_id_len);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
718 putbe64(sidedata_offset,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
719 data + entry_cl2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
720 putbe32(sidedata_comp_len,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
721 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
722 comp_field = data_comp_mode & 3;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
723 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
724 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
725 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
726 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
727 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
728 return NULL;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
729 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
730
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
731 if (self->ntinitialized)
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
732 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
733
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
734 Py_CLEAR(self->headrevs);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
735 Py_RETURN_NONE;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
736 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
737
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
738 /* 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
739 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
740 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
741 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
742 {
47078
223b47235d1c sidedata: enable sidedata computers to optionally rewrite flags
Raphaël Gomès <rgomes@octobus.net>
parents: 47037
diff changeset
743 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
744 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
745 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
746 char comp_mode;
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
747 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
748 #if LONG_MAX == 0x7fffffffL
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
749 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
750 #else
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
751 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
752 #endif
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
753
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
754 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
755 /*
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
756 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
757 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
758 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
759 See issue6485.
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
760 */
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
761 raise_revlog_error();
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
762 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
763 }
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 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
766 &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
767 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
768
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
769 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
770 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
771 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
772 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
773 if (rev < self->length) {
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
774 PyErr_SetString(
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
775 PyExc_IndexError,
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
776 "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
777 return NULL;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
778 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
779
46875
651e6df2b0a4 clang-format: run the formatter on mercurial/cext/revlog.c
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
780 /* 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
781 */
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
782 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
783 if (self->format_version == format_v2) {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
784 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
785 putbe64(sidedata_offset,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
786 data + entry_v2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
787 putbe32(sidedata_comp_len,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
788 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
789 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
790 (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
791 ((comp_mode & 3) << 2);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
792 } 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
793 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
794 putbe64(sidedata_offset,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
795 data + entry_cl2_offset_sidedata_offset);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
796 putbe32(sidedata_comp_len,
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
797 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
798 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
799 (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
800 ((comp_mode & 3) << 2);
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
801 } else {
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
802 raise_revlog_error();
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
803 return NULL;
7dd5a2c0116a revlog: implement changelogv2 packing and unpacking in C
pacien <pacien.trangirard@pacien.net>
parents: 48767
diff changeset
804 }
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
805
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
806 Py_RETURN_NONE;
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
807 }
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
808
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
809 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
810 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
811 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
812 PyObject *s = NULL;
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
813 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
814
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
815 if (obj == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
816 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
817
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
818 #define istat(__n, __d) \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
819 do { \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
820 s = PyBytes_FromString(__d); \
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
821 t = PyLong_FromSsize_t(self->__n); \
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
822 if (!s || !t) \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
823 goto bail; \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
824 if (PyDict_SetItem(obj, s, t) == -1) \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
825 goto bail; \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
826 Py_CLEAR(s); \
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
827 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
828 } while (0)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
829
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
830 if (self->added_length)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
831 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
832 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
833 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
834 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
835 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
836 if (self->ntinitialized) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
837 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
838 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
839 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
840 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
841 }
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
842
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
843 #undef istat
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
844
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
845 return obj;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
846
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
847 bail:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
848 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
849 Py_XDECREF(s);
23948
bd307b462ce2 parsers: avoid leaking several PyObjects in index_stats
Augie Fackler <augie@google.com>
parents: 23947
diff changeset
850 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
851 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
852 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
853
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
854 /*
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
855 * 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
856 * the cached copy.
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
857 */
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
858 static PyObject *list_copy(PyObject *list)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
859 {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
860 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
861 PyObject *newlist = PyList_New(len);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
862 Py_ssize_t i;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
863
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
864 if (newlist == NULL)
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
865 return NULL;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
866
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
867 for (i = 0; i < len; i++) {
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
868 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
869 Py_INCREF(obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
870 PyList_SET_ITEM(newlist, i, obj);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
871 }
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 return newlist;
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
874 }
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
875
34440
7ed0750c71a1 cext: wrap before brace for functions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34438
diff changeset
876 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
877 {
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
878 if (filter) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
879 PyObject *arglist, *result;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
880 int isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
881
26107
50582df9d7a7 parsers: fix two cases of unsigned long instead of Py_ssize_t
Augie Fackler <augie@google.com>
parents: 26098
diff changeset
882 arglist = Py_BuildValue("(n)", arg);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
883 if (!arglist) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
884 return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
885 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
886
46260
abba2d365373 revlog: migrate from PyEval_CallObject to PyObject_Call
Augie Fackler <augie@google.com>
parents: 46224
diff changeset
887 result = PyObject_Call(filter, arglist, NULL);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
888 Py_DECREF(arglist);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
889 if (!result) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
890 return -1;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
891 }
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 /* 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
894 * 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
895 isfiltered = PyObject_IsTrue(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
896 Py_DECREF(result);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
897 return isfiltered;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
898 } else {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
899 return 0;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
900 }
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
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
903 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
904 int parent_2, Py_ssize_t i)
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
905 {
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
906 if (parent_1 >= 0 && phases[parent_1] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
907 phases[i] = phases[parent_1];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
908 if (parent_2 >= 0 && phases[parent_2] > phases[i])
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
909 phases[i] = phases[parent_2];
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
910 }
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
911
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
912 /* Take ownership of a given Python value and add it to a Python list.
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
913 Return -1 on failure (including if [elem] is NULL). */
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
914 static int pylist_append_owned(PyObject *list, PyObject *elem)
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
915 {
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
916 int res;
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
917
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
918 if (elem == NULL)
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
919 return -1;
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
920 res = PyList_Append(list, elem);
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
921 Py_DECREF(elem);
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
922 return res;
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
923 }
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
924
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
925 static PyObject *reachableroots2(indexObject *self, PyObject *args)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
926 {
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
927
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
928 /* Input */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
929 long minroot;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
930 PyObject *includepatharg = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
931 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
932 /* heads and roots are lists */
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
933 PyObject *heads = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
934 PyObject *roots = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
935 PyObject *reachable = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
936
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
937 Py_ssize_t len = index_length(self);
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
938 long revnum;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
939 Py_ssize_t k;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
940 Py_ssize_t i;
26042
2a3010ba6f52 reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents: 26041
diff changeset
941 Py_ssize_t l;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
942 int r;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
943 int parents[2];
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
944
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
945 /* Internal data structure:
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
946 * 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
947 * lentovisit
40561
5c14bf0c5be3 revlog: add blank line in comment to help clang-format
Augie Fackler <augie@google.com>
parents: 40560
diff changeset
948 *
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
949 * 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
950 int *tovisit = NULL;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
951 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
952 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
953 char *revstates = NULL;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
954
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
955 /* Get arguments */
26009
bbb698697efc reachableroots: fix transposition of set and list types in PyArg_ParseTuple
Augie Fackler <augie@google.com>
parents: 26008
diff changeset
956 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
957 &PyList_Type, &roots, &PyBool_Type,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
958 &includepatharg))
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
959 goto bail;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
960
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
961 if (includepatharg == Py_True)
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
962 includepath = 1;
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 /* Initialize return set */
26055
607868eccaa7 reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents: 26054
diff changeset
965 reachable = PyList_New(0);
607868eccaa7 reachableroots: return list of revisions instead of set
Yuya Nishihara <yuya@tcha.org>
parents: 26054
diff changeset
966 if (reachable == NULL)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
967 goto bail;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
968
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
969 /* Initialize internal datastructures */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
970 tovisit = (int *)malloc((len + 1) * sizeof(int));
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
971 if (tovisit == NULL) {
26008
59d57ea69ae6 reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents: 26007
diff changeset
972 PyErr_NoMemory();
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
973 goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
974 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
975
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
976 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
977 if (revstates == NULL) {
26008
59d57ea69ae6 reachableroots: consistently use short-form of PyErr_NoMemory()
Augie Fackler <augie@google.com>
parents: 26007
diff changeset
978 PyErr_NoMemory();
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
979 goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
980 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
981
26053
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
982 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
983 for (i = 0; i < l; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
984 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
985 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
986 goto bail;
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
987 /* 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
988 * 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
989 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
990 continue;
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
991 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
992 }
b68c9d232db6 reachableroots: use internal "revstates" array to test if rev is a root
Yuya Nishihara <yuya@tcha.org>
parents: 26052
diff changeset
993
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
994 /* 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
995 l = PyList_GET_SIZE(heads);
2a3010ba6f52 reachableroots: give anonymous name to short-lived "numheads" variable
Yuya Nishihara <yuya@tcha.org>
parents: 26041
diff changeset
996 for (i = 0; i < l; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
997 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
998 if (revnum == -1 && PyErr_Occurred())
c6115c30a376 reachableroots: verify type of each item of heads argument
Yuya Nishihara <yuya@tcha.org>
parents: 26017
diff changeset
999 goto bail;
26017
44705659da94 reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents: 26016
diff changeset
1000 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
1001 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
1002 goto bail;
44705659da94 reachableroots: verify integer range of heads argument (issue4775)
Yuya Nishihara <yuya@tcha.org>
parents: 26016
diff changeset
1003 }
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
1004 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
1005 tovisit[lentovisit++] = (int)revnum;
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
1006 revstates[revnum + 1] |= RS_SEEN;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1007 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1008 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1009
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1010 /* Visit the tovisit list and find the reachable roots */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1011 k = 0;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1012 while (k < lentovisit) {
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1013 /* 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
1014 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
1015 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
1016 revstates[revnum + 1] |= RS_REACHABLE;
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1017 r = pylist_append_owned(reachable,
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1018 PyLong_FromLong(revnum));
26058
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
1019 if (r < 0)
e7fe0a12376c reachableroots: handle error of PyList_Append()
Yuya Nishihara <yuya@tcha.org>
parents: 26055
diff changeset
1020 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
1021 if (includepath == 0)
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1022 continue;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1023 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1024
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1025 /* 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
1026 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
1027 continue;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1028 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
1029 if (r < 0)
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1030 goto bail;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1031 for (i = 0; i < 2; i++) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1032 if (!(revstates[parents[i] + 1] & RS_SEEN) &&
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1033 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
1034 tovisit[lentovisit++] = parents[i];
26044
b3ad349d0e50 reachableroots: extend "revstates" to array of bit flags
Yuya Nishihara <yuya@tcha.org>
parents: 26043
diff changeset
1035 revstates[parents[i] + 1] |= RS_SEEN;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1036 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1037 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1038 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1039
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1040 /* 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
1041 * and add them to the reachable set */
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1042 if (includepath == 1) {
26080
83c9edcac05c reachableroots: silence warning of implicit integer narrowing issued by clang
Yuya Nishihara <yuya@tcha.org>
parents: 26079
diff changeset
1043 long minidx = minroot;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1044 if (minidx < 0)
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1045 minidx = 0;
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1046 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
1047 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
1048 continue;
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1049 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
1050 /* 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
1051 * index_get_parents */
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1052 if (r < 0)
8da628be211b reachableroots: reduce nesting level by jumping to next iteration by continue
Yuya Nishihara <yuya@tcha.org>
parents: 26033
diff changeset
1053 goto bail;
26059
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1054 if (((revstates[parents[0] + 1] |
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1055 revstates[parents[1] + 1]) &
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1056 RS_REACHABLE) &&
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1057 !(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
1058 revstates[i + 1] |= RS_REACHABLE;
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1059 r = pylist_append_owned(reachable,
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1060 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
1061 if (r < 0)
8779ce81ea80 reachableroots: unroll loop that checks if one of parents is reachable
Yuya Nishihara <yuya@tcha.org>
parents: 26058
diff changeset
1062 goto bail;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1063 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1064 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1065 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1066
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
1067 free(revstates);
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1068 free(tovisit);
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1069 return reachable;
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
1070 bail:
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1071 Py_XDECREF(reachable);
26043
f2f0a3ab6e41 reachableroots: rename "seen" array to "revstates" for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 26042
diff changeset
1072 free(revstates);
26016
c8d41c9c23c7 reachableroots: unify bail cases to raise exception correctly
Yuya Nishihara <yuya@tcha.org>
parents: 26015
diff changeset
1073 free(tovisit);
26010
2c03e521a0c5 reachableroots: return NULL if we're throwing an exception
Augie Fackler <augie@google.com>
parents: 26009
diff changeset
1074 return NULL;
26004
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1075 }
ff89383a97db reachableroots: add a C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25911
diff changeset
1076
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1077 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
1078 char phase)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1079 {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1080 Py_ssize_t len = index_length(self);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1081 PyObject *item;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1082 PyObject *iterator;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1083 int rev, minrev = -1;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1084 char *node;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1085
45175
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1086 if (!PySet_Check(roots)) {
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1087 PyErr_SetString(PyExc_TypeError,
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1088 "roots must be a set of nodes");
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1089 return -2;
45175
211063648b29 phases: fix error return with no exception from computephases()
Yuya Nishihara <yuya@tcha.org>
parents: 45173
diff changeset
1090 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1091 iterator = PyObject_GetIter(roots);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1092 if (iterator == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1093 return -2;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1094 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
1095 if (node_check(self->nodelen, item, &node) == -1)
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1096 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
1097 rev = index_find_node(self, node);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1098 /* null is implicitly public, so negative is invalid */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1099 if (rev < 0 || rev >= len)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1100 goto failed;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1101 phases[rev] = phase;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1102 if (minrev == -1 || minrev > rev)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1103 minrev = rev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1104 Py_DECREF(item);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1105 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1106 Py_DECREF(iterator);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1107 return minrev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1108 failed:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1109 Py_DECREF(iterator);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1110 Py_DECREF(item);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1111 return -2;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1112 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1113
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
1114 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
1115 {
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1116 /* 0: public (untracked), 1: draft, 2: secret, 32: archive,
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1117 96: internal */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1118 static const char trackedphases[] = {1, 2, 32, 96};
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1119 PyObject *roots = Py_None;
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1120 PyObject *phasesetsdict = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1121 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
1122 Py_ssize_t len = index_length(self);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1123 char *phases = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1124 int minphaserev = -1, rev, i;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1125 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
1126
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1127 if (!PyArg_ParseTuple(args, "O", &roots))
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1128 return NULL;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1129 if (roots == NULL || !PyDict_Check(roots)) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1130 PyErr_SetString(PyExc_TypeError, "roots must be a dictionary");
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1131 return NULL;
36623
a472a897c340 cext: fix computephasesmapsets() not to return without setting an exception
Yuya Nishihara <yuya@tcha.org>
parents: 36621
diff changeset
1132 }
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1133
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1134 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
1135 if (phases == NULL) {
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1136 PyErr_NoMemory();
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1137 return NULL;
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1138 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1139
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1140 for (i = 0; i < numphases; ++i) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1141 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
1142 PyObject *phaseroots = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1143 if (pyphase == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1144 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1145 phaseroots = PyDict_GetItem(roots, pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1146 Py_DECREF(pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1147 if (phaseroots == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1148 continue;
45176
3264d58e8b06 phases: fix clang-format error
Yuya Nishihara <yuya@tcha.org>
parents: 45175
diff changeset
1149 rev = add_roots_get_min(self, phaseroots, phases,
3264d58e8b06 phases: fix clang-format error
Yuya Nishihara <yuya@tcha.org>
parents: 45175
diff changeset
1150 trackedphases[i]);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1151 if (rev == -2)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1152 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1153 if (rev != -1 && (minphaserev == -1 || rev < minphaserev))
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1154 minphaserev = rev;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1155 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1156
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1157 for (i = 0; i < numphases; ++i) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1158 phasesets[i] = PySet_New(NULL);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1159 if (phasesets[i] == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1160 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1161 }
25190
22438cfd11b5 phases: add set per phase in C phase computation
Laurent Charignon <lcharignon@fb.com>
parents: 24879
diff changeset
1162
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1163 if (minphaserev == -1)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1164 minphaserev = len;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1165 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
1166 PyObject *pyphase = NULL;
a6fde9d789d9 phases: move short-lived PyObject pointers to local scope
Yuya Nishihara <yuya@tcha.org>
parents: 45179
diff changeset
1167 PyObject *pyrev = NULL;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1168 int parents[2];
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 * The parent lookup could be skipped for phaseroots, but
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1171 * phase --force would historically not recompute them
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1172 * correctly, leaving descendents with a lower phase around.
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1173 * As such, unconditionally recompute the phase.
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1174 */
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1175 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
1176 goto release;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1177 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
1178 switch (phases[rev]) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1179 case 0:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1180 continue;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1181 case 1:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1182 pyphase = phasesets[0];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1183 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1184 case 2:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1185 pyphase = phasesets[1];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1186 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1187 case 32:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1188 pyphase = phasesets[2];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1189 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1190 case 96:
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1191 pyphase = phasesets[3];
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1192 break;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1193 default:
45177
03332e5f67e9 phases: make sure an exception should be set on error return
Yuya Nishihara <yuya@tcha.org>
parents: 45176
diff changeset
1194 /* 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
1195 * 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
1196 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
1197 "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
1198 goto release;
36623
a472a897c340 cext: fix computephasesmapsets() not to return without setting an exception
Yuya Nishihara <yuya@tcha.org>
parents: 36621
diff changeset
1199 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1200 pyrev = PyLong_FromLong(rev);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1201 if (pyrev == NULL)
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1202 goto release;
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1203 if (PySet_Add(pyphase, pyrev) == -1) {
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1204 Py_DECREF(pyrev);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1205 goto release;
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1206 }
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1207 Py_DECREF(pyrev);
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1208 }
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1209
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1210 phasesetsdict = _dict_new_presized(numphases);
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1211 if (phasesetsdict == NULL)
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1212 goto release;
45141
9719e118e4af cext: remove unused variables
Joerg Sonnenberger <joerg@bec.de>
parents: 45131
diff changeset
1213 for (i = 0; i < numphases; ++i) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1214 PyObject *pyphase = PyLong_FromLong(trackedphases[i]);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1215 if (pyphase == NULL)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1216 goto release;
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1217 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
1218 -1) {
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1219 Py_DECREF(pyphase);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1220 goto release;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1221 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1222 Py_DECREF(phasesets[i]);
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1223 phasesets[i] = NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1224 }
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1225
47343
9f798c1b0d89 cext: fix memory leak in phases computation
Georges Racinet <georges.racinet@octobus.net>
parents: 46974
diff changeset
1226 free(phases);
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1227 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
1228
27364
ad1cc1435b13 parsers: simplify error logic in compute_phases_map_sets
Bryan O'Sullivan <bos@serpentine.com>
parents: 27341
diff changeset
1229 release:
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1230 for (i = 0; i < numphases; ++i)
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1231 Py_XDECREF(phasesets[i]);
45179
ba5e4b11d085 phases: rename variable used for owned dict of phasesets
Yuya Nishihara <yuya@tcha.org>
parents: 45178
diff changeset
1232 Py_XDECREF(phasesetsdict);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1233
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1234 free(phases);
45131
61e7464477ac phases: sparsify phaseroots and phasesets
Joerg Sonnenberger <joerg@bec.de>
parents: 44587
diff changeset
1235 return NULL;
24443
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1236 }
539b3c7eea44 phase: compute phases in C
Laurent Charignon <lcharignon@fb.com>
parents: 24214
diff changeset
1237
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1238 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
1239 {
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1240 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
1241 char *nothead = NULL;
22540
9a860ac8c216 parsers: fix uninitialize variable warning
David Soria Parra <davidsp@fb.com>
parents: 22484
diff changeset
1242 PyObject *heads = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1243 PyObject *filter = NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1244 PyObject *filteredrevs = Py_None;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1245
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1246 if (!PyArg_ParseTuple(args, "|O", &filteredrevs)) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1247 return NULL;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1248 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1249
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1250 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
1251 return list_copy(self->headrevs);
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
1252
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1253 Py_DECREF(self->filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1254 self->filteredrevs = filteredrevs;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1255 Py_INCREF(filteredrevs);
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1256
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1257 if (filteredrevs != Py_None) {
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1258 filter = PyObject_GetAttrString(filteredrevs, "__contains__");
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1259 if (!filter) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1260 PyErr_SetString(
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1261 PyExc_TypeError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1262 "filteredrevs has no attribute __contains__");
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1263 goto bail;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1264 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1265 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1266
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
1267 len = index_length(self);
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1268 heads = PyList_New(0);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1269 if (heads == NULL)
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 if (len == 0) {
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1272 if (pylist_append_owned(heads, PyLong_FromLong(-1)) == -1) {
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1273 Py_XDECREF(nullid);
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1274 goto bail;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1275 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1276 goto done;
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1277 }
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1278
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1279 nothead = calloc(len, 1);
27366
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
1280 if (nothead == NULL) {
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
1281 PyErr_NoMemory();
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1282 goto bail;
27366
7e8a883da171 parsers: add a missed PyErr_NoMemory
Bryan O'Sullivan <bos@serpentine.com>
parents: 27365
diff changeset
1283 }
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1284
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1285 for (i = len - 1; i >= 0; i--) {
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1286 int isfiltered;
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1287 int parents[2];
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1288
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1289 /* 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
1290 * 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
1291 * 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
1292 */
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1293 if (nothead[i] != 1) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1294 isfiltered = check_filter(filter, i);
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1295 if (isfiltered == -1) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1296 PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1297 "unable to check filter");
28386
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1298 goto bail;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1299 }
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1300
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1301 if (isfiltered) {
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1302 nothead[i] = 1;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1303 continue;
1c658391b22f parsers: optimize filtered headrevs logic
Durham Goode <durham@fb.com>
parents: 27638
diff changeset
1304 }
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1305 }
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
1306
25860
895f04955a49 parsers: silence warning of implicit integer conversion issued by clang
Yuya Nishihara <yuya@tcha.org>
parents: 25810
diff changeset
1307 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
1308 goto bail;
25297
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1309 for (j = 0; j < 2; j++) {
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1310 if (parents[j] >= 0)
3966e39fea98 changelog: fix bug in heads computation
Laurent Charignon <lcharignon@fb.com>
parents: 25296
diff changeset
1311 nothead[parents[j]] = 1;
16786
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1312 }
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
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1315 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
1316 if (nothead[i])
2631cd5dd244 revlog: switch to a C version of headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16784
diff changeset
1317 continue;
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1318 if (pylist_append_owned(heads, PyLong_FromSsize_t(i)) == -1) {
16786
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
51396
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1335 /* "rgs" stands for "reverse growable set".
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1336 It is a representation of a set of integers that can't exceed, but
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1337 tend to be close to `max`.
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1338
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1339 `body` is a growable bit array covering the range `max-len+1..max`,
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1340 in reverse order.
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1341 `sum` keeps track of the cardinality of the set.
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1342 */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1343 typedef struct rgs {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1344 int max;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1345 int len;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1346 char *body;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1347 int sum;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1348 } rgs;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1349
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1350 static int rgs_offset(rgs *rgs, int i)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1351 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1352 return rgs->max - i;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1353 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1354
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1355 /* returns 1 on success, 0 on failure */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1356 static int rgs_alloc(rgs *rgs, int max)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1357 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1358 int new_len = 64;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1359 char *new_body = calloc(new_len, 1);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1360 if (new_body == NULL)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1361 return 0;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1362 rgs->len = new_len;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1363 rgs->body = new_body;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1364 rgs->max = max;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1365 rgs->sum = 0;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1366 return 1;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1367 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1368
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1369 static bool rgs_get(rgs *rgs, int i)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1370 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1371 int offset = rgs_offset(rgs, i);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1372 if (offset >= rgs->len) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1373 return 0;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1374 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1375 if (offset < 0) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1376 abort();
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1377 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1378 return rgs->body[offset];
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1379 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1380
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1381 /* Realloc `body` to length `new_len`.
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1382 Returns -1 when out of memory. */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1383 static int rgs_realloc(rgs *rgs, int new_len)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1384 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1385 int old_len = rgs->len;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1386 char *old_body = rgs->body;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1387 char *new_body = calloc(new_len, 1);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1388 assert(new_len >= old_len);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1389 if (new_body == NULL)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1390 return -1;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1391 memcpy(new_body, old_body, old_len);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1392 free(old_body);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1393 rgs->body = new_body;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1394 rgs->len = new_len;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1395 return 0;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1396 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1397
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1398 /* Realloc the rgs `body` to include the `offset` */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1399 static int rgs_realloc_amortized(rgs *rgs, int offset)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1400 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1401 int old_len = rgs->len;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1402 int new_len = old_len * 4;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1403 if (offset >= new_len)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1404 new_len = offset + 1;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1405 return rgs_realloc(rgs, new_len);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1406 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1407
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1408 /* returns 0 on success, -1 on error */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1409 static int rgs_set(rgs *rgs, int i, bool v)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1410 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1411 int offset = rgs_offset(rgs, i);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1412 if (offset >= rgs->len) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1413 if (v == 0) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1414 /* no-op change: no need to resize */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1415 return 0;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1416 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1417 if (rgs_realloc_amortized(rgs, offset) == -1)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1418 return -1;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1419 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1420 if (offset < 0) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1421 abort();
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1422 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1423 rgs->sum -= rgs->body[offset];
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1424 rgs->sum += v;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1425 rgs->body[offset] = v;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1426 return 0;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1427 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1428
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1429 /* Add a size_t value to a Python list. Return -1 on failure. */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1430 static inline int pylist_append_size_t(PyObject *list, size_t v)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1431 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1432 return pylist_append_owned(list, PyLong_FromSsize_t(v));
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1433 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1434
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1435 static PyObject *index_headrevsdiff(indexObject *self, PyObject *args)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1436 {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1437 int begin, end;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1438 Py_ssize_t i, j;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1439 PyObject *heads_added = NULL;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1440 PyObject *heads_removed = NULL;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1441 PyObject *res = NULL;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1442 rgs rgs;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1443 rgs.body = NULL;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1444
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1445 if (!PyArg_ParseTuple(args, "ii", &begin, &end))
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1446 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1447
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1448 if (!rgs_alloc(&rgs, end))
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1449 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1450
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1451 heads_added = PyList_New(0);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1452 if (heads_added == NULL)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1453 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1454 heads_removed = PyList_New(0);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1455 if (heads_removed == NULL)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1456 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1457
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1458 for (i = end - 1; i >= begin; i--) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1459 int parents[2];
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1460
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1461 if (rgs_get(&rgs, i)) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1462 if (rgs_set(&rgs, i, false) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1463 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1464 };
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1465 } else {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1466 if (pylist_append_size_t(heads_added, i) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1467 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1468 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1469 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1470
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1471 if (index_get_parents(self, i, parents, i) < 0)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1472 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1473 for (j = 0; j < 2; j++) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1474 if (parents[j] >= 0)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1475 if (rgs_set(&rgs, parents[j], true) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1476 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1477 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1478 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1479 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1480
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1481 while (rgs.sum) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1482 int parents[2];
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1483
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1484 if (rgs_get(&rgs, i)) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1485 if (rgs_set(&rgs, i, false) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1486 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1487 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1488 if (pylist_append_size_t(heads_removed, i) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1489 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1490 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1491 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1492
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1493 if (index_get_parents(self, i, parents, i) < 0)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1494 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1495 for (j = 0; j < 2; j++) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1496 if (parents[j] >= 0)
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1497 if (rgs_set(&rgs, parents[j], false) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1498 /* can't actually fail */
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1499 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1500 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1501 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1502 i--;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1503 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1504
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1505 if (begin == 0 && end > 0) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1506 if (pylist_append_size_t(heads_removed, -1) == -1) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1507 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1508 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1509 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1510
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1511 if (!(res = PyTuple_Pack(2, heads_removed, heads_added))) {
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1512 goto bail;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1513 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1514
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1515 Py_XDECREF(heads_removed);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1516 Py_XDECREF(heads_added);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1517 free(rgs.body);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1518 return res;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1519 bail:
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1520 Py_XDECREF(heads_added);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1521 Py_XDECREF(heads_removed);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1522 free(rgs.body);
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1523 return NULL;
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1524 }
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
1525
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1526 /**
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1527 * 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
1528 *
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1529 * 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
1530 */
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1531 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
1532 {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1533 const char *data;
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1534 int result;
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1535
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
1536 data = index_deref(self, rev);
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
1537 if (data == NULL)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
1538 return -2;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1539
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1540 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1541 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
1542 } 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
1543 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
1544 } 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
1545 return rev;
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1546 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1547 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1548 return -1;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
1549 }
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1550
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1551 if (result > rev) {
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1552 PyErr_Format(
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1553 PyExc_ValueError,
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1554 "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
1555 rev, result);
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1556 return -2;
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1557 }
41019
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1558 if (result < -1) {
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1559 PyErr_Format(
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1560 PyExc_ValueError,
41283
4948b327d3b9 cext: clang-format new code coming from stable branch
Yuya Nishihara <yuya@tcha.org>
parents: 41129
diff changeset
1561 "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
1562 result);
41019
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1563 return -2;
7542466b94e2 revlog: cache delta base value under -1
Boris Feld <boris.feld@octobus.net>
parents: 41018
diff changeset
1564 }
41018
f4113489e4d4 revlog: catch revlog corruption in index_baserev
Boris Feld <boris.feld@octobus.net>
parents: 40813
diff changeset
1565 return result;
33171
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
41085
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1568 /**
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1569 * 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
1570 *
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1571 * Only relevant for sparse-revlog case.
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1572 * 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
1573 */
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1574 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
1575 {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1576 int ps[2];
49476
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1577 int b;
41085
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1578 Py_ssize_t base;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1579 while (rev >= 0) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1580 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
1581 if (base == rev) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1582 base = -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1583 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1584 if (base == -2) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1585 assert(PyErr_Occurred());
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1586 return -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1587 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1588 if (base == -1) {
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1589 return 1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1590 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1591 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
1592 assert(PyErr_Occurred());
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1593 return -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1594 };
49476
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1595 while ((index_get_length(self, ps[0]) == 0) && ps[0] >= 0) {
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1596 b = index_baserev(self, ps[0]);
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1597 if (b == ps[0]) {
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1598 break;
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1599 }
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1600 ps[0] = b;
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1601 }
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1602 while ((index_get_length(self, ps[1]) == 0) && ps[1] >= 0) {
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1603 b = index_baserev(self, ps[1]);
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1604 if (b == ps[1]) {
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1605 break;
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1606 }
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1607 ps[1] = b;
5846bc8a2855 revlog: finer computation of "issnapshot"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49212
diff changeset
1608 }
41085
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1609 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
1610 return 0;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1611 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1612 rev = base;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1613 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1614 return rev == -1;
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1615 }
a6556b09bf83 revlog: add a native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41078
diff changeset
1616
41086
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1617 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
1618 {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1619 long rev;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1620 int issnap;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1621 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
1622
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1623 if (!pylong_to_long(value, &rev)) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1624 return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1625 }
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1626 if (rev < -1 || rev >= length) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1627 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
1628 rev);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1629 return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1630 };
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1631 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
1632 if (issnap < 0) {
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1633 return NULL;
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1634 };
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1635 return PyBool_FromLong((long)issnap);
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1636 }
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
1637
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1638 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
1639 {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1640 Py_ssize_t start_rev;
49678
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1641 Py_ssize_t end_rev;
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1642 PyObject *cache;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1643 Py_ssize_t base;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1644 Py_ssize_t rev;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1645 PyObject *key = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1646 PyObject *value = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1647 const Py_ssize_t length = index_length(self);
49678
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1648 if (!PyArg_ParseTuple(args, "O!nn", &PyDict_Type, &cache, &start_rev,
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1649 &end_rev)) {
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1650 return NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1651 }
49678
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1652 end_rev += 1;
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1653 if (end_rev > length) {
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1654 end_rev = length;
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1655 }
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1656 if (start_rev < 0) {
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1657 start_rev = 0;
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1658 }
efbbc2f9121e delta-find: use a smarter object for snapshot caching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49476
diff changeset
1659 for (rev = start_rev; rev < end_rev; rev++) {
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1660 int issnap;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1661 PyObject *allvalues = NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1662 issnap = index_issnapshotrev(self, rev);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1663 if (issnap < 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1664 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1665 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1666 if (issnap == 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1667 continue;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1668 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1669 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
1670 if (base == rev) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1671 base = -1;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1672 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1673 if (base == -2) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1674 assert(PyErr_Occurred());
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1675 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1676 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1677 key = PyLong_FromSsize_t(base);
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1678 allvalues = PyDict_GetItem(cache, key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1679 if (allvalues == NULL && PyErr_Occurred()) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1680 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1681 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1682 if (allvalues == NULL) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1683 int r;
49679
b670eb3dd6c9 delta-find: use sets instead of list in the snapshot cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49678
diff changeset
1684 allvalues = PySet_New(0);
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1685 if (!allvalues) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1686 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1687 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1688 r = PyDict_SetItem(cache, key, allvalues);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1689 Py_DECREF(allvalues);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1690 if (r < 0) {
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1691 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1692 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1693 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1694 value = PyLong_FromSsize_t(rev);
49679
b670eb3dd6c9 delta-find: use sets instead of list in the snapshot cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49678
diff changeset
1695 if (PySet_Add(allvalues, value)) {
41108
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1696 goto bail;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1697 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1698 Py_CLEAR(key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1699 Py_CLEAR(value);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1700 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1701 Py_RETURN_NONE;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1702 bail:
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1703 Py_XDECREF(key);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1704 Py_XDECREF(value);
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1705 return NULL;
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1706 }
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
1707
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1708 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
1709 {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1710 int rev, generaldelta;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1711 PyObject *stoparg;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1712 int stoprev, iterrev, baserev = -1;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1713 int stopped;
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1714 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
1715 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
1716
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1717 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
1718 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1719 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1720
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1721 if (PyLong_Check(stoparg)) {
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1722 stoprev = (int)PyLong_AsLong(stoparg);
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1723 if (stoprev == -1 && PyErr_Occurred()) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1724 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1725 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1726 } else if (stoparg == Py_None) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1727 stoprev = -2;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1728 } else {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1729 PyErr_SetString(PyExc_ValueError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1730 "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
1731 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1732 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1733
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
1734 if (rev < 0 || rev >= length) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1735 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
1736 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1737 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1738
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1739 chain = PyList_New(0);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1740 if (chain == NULL) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1741 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1742 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1743
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1744 baserev = index_baserev(self, rev);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1745
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1746 /* This should never happen. */
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1747 if (baserev <= -2) {
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1748 /* 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
1749 assert(PyErr_Occurred());
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1750 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1751 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1752
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1753 iterrev = rev;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1754
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1755 while (iterrev != baserev && iterrev != stoprev) {
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1756 if (pylist_append_owned(chain, PyLong_FromLong(iterrev))) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1757 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1758 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1759
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1760 if (generaldelta) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1761 iterrev = baserev;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1762 } else {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1763 iterrev--;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1764 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1765
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1766 if (iterrev < 0) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1767 break;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1768 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1769
38868
0db50770f388 index: don't add 1 to length variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 38867
diff changeset
1770 if (iterrev >= length) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1771 PyErr_SetString(PyExc_IndexError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1772 "revision outside index");
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1773 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1774 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1775
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1776 baserev = index_baserev(self, iterrev);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1777
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1778 /* This should never happen. */
33174
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1779 if (baserev <= -2) {
f4f52bb362e6 revlog: address review feedback for deltachain C implementation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33171
diff changeset
1780 /* 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
1781 assert(PyErr_Occurred());
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1782 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1783 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1784 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1785
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1786 if (iterrev == stoprev) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1787 stopped = 1;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
1788 } else {
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
1789 if (pylist_append_owned(chain, PyLong_FromLong(iterrev))) {
33171
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1790 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1791 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1792
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1793 stopped = 0;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1794 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1795
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1796 if (PyList_Reverse(chain)) {
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1797 goto bail;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1798 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1799
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1800 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
1801 Py_DECREF(chain);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1802 return result;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1803
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1804 bail:
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1805 Py_DECREF(chain);
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1806 return NULL;
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1807 }
6d678ab1b10d revlog: C implementation of delta chain resolution
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32384
diff changeset
1808
40705
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1809 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
1810 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
1811 {
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1812 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
1813 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
1814 int end_size;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1815 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
1816 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
1817 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1818 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1819 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
1820 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
1821 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1822 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1823 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
1824 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
1825 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1826 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1827 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
1828 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
1829 "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
1830 "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
1831 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
1832 return -1;
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1833 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1834 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
1835 }
4ec6a24029d2 sparse-revlog: add a `index_segment_span` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40704
diff changeset
1836
40742
8edca70dc951 revlog: update the documentation for `trim_endidx`
Boris Feld <boris.feld@octobus.net>
parents: 40741
diff changeset
1837 /* 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
1838 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
1839 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
1840 {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1841 int length;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1842 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
1843 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
1844 if (length < 0) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1845 return -1;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1846 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1847 if (length != 0) {
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1848 break;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1849 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1850 endidx -= 1;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1851 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1852 return endidx;
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1853 }
0650be877a37 sparse-revlog: add a `trim_endidx` function in C
Boris Feld <boris.feld@octobus.net>
parents: 40705
diff changeset
1854
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1855 struct Gap {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1856 int64_t size;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1857 Py_ssize_t idx;
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
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1860 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
1861 {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1862 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
1863 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
1864 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
1865 return -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1866 } 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
1867 return 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1868 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1869 return 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1870 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1871 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
1872 {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1873 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
1874 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
1875 if (l_left < l_right) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1876 return -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1877 } 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
1878 return 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1879 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1880 return 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1881 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1882
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1883 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
1884 {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1885 /* method arguments */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1886 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
1887 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
1888 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
1889
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1890 /* other core variables */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1891 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
1892 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
1893 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
1894
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1895 /* 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
1896 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
1897 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
1898 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
1899 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
1900
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1901 /* 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
1902 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
1903 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
1904 int64_t previous_end;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1905 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
1906 Py_ssize_t num_gaps =
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1907 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
1908 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
1909 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
1910 PyObject *allchunks = NULL; /* all slices */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1911 Py_ssize_t previdx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1912
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1913 /* parsing argument */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1914 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
1915 &targetdensity, &mingapsize)) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1916 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1917 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1918
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1919 /* 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
1920 */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1921 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
1922 if (num_revs <= 1) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1923 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
1924 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1925 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1926
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1927 /* 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
1928 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
1929 if (revs == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1930 PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1931 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1932 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1933 for (i = 0; i < num_revs; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1934 Py_ssize_t revnum =
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
1935 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
1936 if (revnum == -1 && PyErr_Occurred()) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1937 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1938 }
40963
2e305e54eae3 sparse-revlog: protect C code against delta chain including nullrev
Boris Feld <boris.feld@octobus.net>
parents: 40962
diff changeset
1939 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
1940 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
1941 "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
1942 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1943 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1944 revs[i] = revnum;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1945 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1946
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1947 /* 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
1948 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
1949 if (deltachainspan < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1950 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1951 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1952
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1953 if (deltachainspan <= mingapsize) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1954 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
1955 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1956 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1957 chainpayload = 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1958 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
1959 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
1960 if (tmp < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1961 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1962 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1963 chainpayload += tmp;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1964 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1965
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1966 readdata = deltachainspan;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1967 density = 1.0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1968
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1969 if (0 < deltachainspan) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1970 density = (double)chainpayload / (double)deltachainspan;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1971 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1972
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1973 if (density >= targetdensity) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1974 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
1975 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1976 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1977
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1978 /* 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
1979 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
1980 if (gaps == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1981 PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1982 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1983 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1984
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1985 previous_end = -1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1986 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
1987 int64_t revstart;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1988 int revsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1989 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
1990 if (revstart < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1991 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1992 };
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1993 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
1994 if (revsize < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1995 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1996 };
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1997 if (revsize == 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1998 continue;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
1999 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2000 if (previous_end >= 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2001 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
2002 if (gapsize > mingapsize) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2003 gaps[num_gaps].size = gapsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2004 gaps[num_gaps].idx = i;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2005 num_gaps += 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2006 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2007 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2008 previous_end = revstart + revsize;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2009 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2010 if (num_gaps == 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2011 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
2012 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2013 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2014 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
2015
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2016 /* 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
2017 selected_indices =
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2018 (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
2019 if (selected_indices == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2020 PyErr_NoMemory();
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2021 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2022 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2023
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2024 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
2025 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
2026 readdata -= gaps[i].size;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2027 num_selected += 1;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2028 if (readdata <= 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2029 density = 1.0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2030 } else {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2031 density = (double)chainpayload / (double)readdata;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2032 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2033 if (density >= targetdensity) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2034 break;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2035 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2036 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2037 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
2038 &Py_ssize_t_compare);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2039
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2040 /* create the resulting slice */
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2041 allchunks = PyList_New(0);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2042 if (allchunks == NULL) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2043 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2044 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2045 previdx = 0;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2046 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
2047 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
2048 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
2049 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
2050 if (endidx < 0) {
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2051 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2052 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2053 if (previdx < endidx) {
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
2054 PyObject *chunk =
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
2055 PyList_GetSlice(list_revs, previdx, endidx);
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
2056 if (pylist_append_owned(allchunks, chunk) == -1) {
40707
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2057 goto bail;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2058 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2059 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2060 previdx = idx;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2061 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2062 result = allchunks;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2063 goto done;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2064
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2065 bail:
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2066 Py_XDECREF(allchunks);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2067 done:
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2068 free(revs);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2069 free(gaps);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2070 free(selected_indices);
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2071 return result;
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2072 }
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
2073
16618
6bae941b58ad parsers: change the type of nt_level
Bryan O'Sullivan <bryano@fb.com>
parents: 16617
diff changeset
2074 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
2075 {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2076 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
2077 if (!(level & 1))
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2078 v >>= 4;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2079 return v & 0xf;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2080 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2081
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2082 /*
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2083 * Return values:
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2084 *
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2085 * -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
2086 * -2: not found
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2087 * rest: valid rev
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2088 */
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2089 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
2090 int hex)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2091 {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2092 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
2093 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
2094
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2095 /* 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
2096 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
2097 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
2098 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2099
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2100 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
2101 maxlevel = nodelen;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2102 else
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2103 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
2104 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
2105 maxlevel = 2 * self->nodelen;
16641
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
2106
e6dfbc5df76f parsers: use the correct maximum radix tree depth
Bryan O'Sullivan <bryano@fb.com>
parents: 16604
diff changeset
2107 for (level = off = 0; level < maxlevel; level++) {
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2108 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
2109 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
2110 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
2111
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2112 if (v < 0) {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2113 const char *n;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2114 Py_ssize_t i;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2115
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
2116 v = -(v + 2);
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2117 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
2118 if (n == NULL)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2119 return -2;
16663
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2120 for (i = level; i < maxlevel; i++)
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2121 if (getnybble(node, i) != nt_level(n, i))
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2122 return -2;
a955e05dd7a0 parsers: allow hex keys
Bryan O'Sullivan <bryano@fb.com>
parents: 16642
diff changeset
2123 return v;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2124 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2125 if (v == 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2126 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2127 off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2128 }
16616
8f79aabd96f6 parsers: allow nt_find to signal an ambiguous match
Bryan O'Sullivan <bryano@fb.com>
parents: 16615
diff changeset
2129 /* 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
2130 return -4;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2131 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2132
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
2133 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
2134 {
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
2135 if (self->length == self->capacity) {
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
2136 size_t newcapacity;
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
2137 nodetreenode *newnodes;
39071
06ff7ea4f440 index: avoid duplicating capacity-growth expression
Martin von Zweigbergk <martinvonz@google.com>
parents: 39070
diff changeset
2138 newcapacity = self->capacity * 2;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
2139 if (newcapacity >= SIZE_MAX / sizeof(nodetreenode)) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2140 PyErr_SetString(PyExc_MemoryError,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2141 "overflow in nt_new");
24623
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
2142 return -1;
2262d7bc469e parsers: check for memory allocation overflows more carefully
Bryan O'Sullivan <bryano@fb.com>
parents: 24622
diff changeset
2143 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2144 newnodes =
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2145 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
2146 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
2147 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
2148 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2149 }
38938
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
2150 self->capacity = newcapacity;
dcd395dc98d8 index: remove side-effect from failed nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38937
diff changeset
2151 self->nodes = newnodes;
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
2152 memset(&self->nodes[self->length], 0,
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
2153 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
2154 }
38915
fff675dfb80b index: pass only nodetree to nt_new()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38914
diff changeset
2155 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
2156 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2157
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2158 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
2159 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2160 int level = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2161 int off = 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2162
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2163 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
2164 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
2165 nodetreenode *n;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2166 int v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2167
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2168 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
2169 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
2170
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2171 if (v == 0) {
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
2172 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
2173 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2174 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2175 if (v < 0) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2176 const char *oldnode =
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2177 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
2178 int noff;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2179
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
2180 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
2181 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
2182 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
2183 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
2184 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2185 }
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2186 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
2187 if (noff == -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2188 return -1;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2189 /* 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
2190 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
2191 off = noff;
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2192 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
2193 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
2194 if (level > self->depth)
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2195 self->depth = level;
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2196 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
2197 } else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2198 level += 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2199 off = v;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2200 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2201 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2202
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2203 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2204 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2205
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2206 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
2207 {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2208 Py_ssize_t rev;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2209 const char *node;
39227
42cc76d0f836 cext: fix revlog compiler error on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 39226
diff changeset
2210 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
2211 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
2212 return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2213 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
2214 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
2215 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
2216 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2217 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2218 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
2219 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
2220 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2221 Py_RETURN_NONE;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2222 }
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2223
38940
b6fb71a0a005 index: make most "nt_*" functions take a nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38939
diff changeset
2224 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
2225 {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2226 /* 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
2227 */
38846
f738c502e43b index: store nullrev as -1 in nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38845
diff changeset
2228 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
2229 }
f9fc59ea3135 index: create function for deleting node from nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38821
diff changeset
2230
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2231 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
2232 {
39225
fcaffbd7e635 index: fix a comment about overflow-checking
Martin von Zweigbergk <martinvonz@google.com>
parents: 39219
diff changeset
2233 /* 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
2234 self->nodes = NULL;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2235
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2236 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
2237 /* 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
2238 * 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
2239 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
2240 self->nodelen = index->nodelen;
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2241 self->depth = 0;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2242 self->splits = 0;
46224
fcc324a228fe revlog: use size_t for nodetree capacity
Jun Wu <quark@fb.com>
parents: 46144
diff changeset
2243 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
2244 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
2245 return -1;
4dd92a15fcca index: move check for too large capacity into nt_init()
Martin von Zweigbergk <martinvonz@google.com>
parents: 39069
diff changeset
2246 }
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2247 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
2248 if (self->nodes == NULL) {
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2249 PyErr_NoMemory();
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2250 return -1;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2251 }
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2252 self->length = 1;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2253 return 0;
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2254 }
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2255
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2256 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
2257 {
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2258 PyObject *index;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2259 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
2260 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
2261 &capacity))
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2262 return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2263 Py_INCREF(index);
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2264 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
2265 }
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2266
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2267 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
2268 {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2269 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
2270 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2271
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2272 /*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2273 * 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
2274 *
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2275 * Return values:
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2276 *
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2277 * -3: error (exception set)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2278 * -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
2279 * rest: length of shortest prefix
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2280 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2281 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
2282 {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2283 int level, off;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2284
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2285 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
2286 int k, v;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2287 nodetreenode *n = &self->nodes[off];
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2288 k = nt_level(node, level);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2289 v = n->children[k];
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2290 if (v < 0) {
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2291 const char *n;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2292 v = -(v + 2);
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2293 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
2294 if (n == NULL)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2295 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
2296 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
2297 /*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2298 * 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
2299 * 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
2300 * not exist).
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2301 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2302 return -2;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2303 return level + 1;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2304 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2305 if (v == 0)
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2306 return -2;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2307 off = v;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2308 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2309 /*
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2310 * 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
2311 * 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
2312 * 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
2313 */
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2314 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
2315 return -3;
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2316 }
2b89e20c450c index: move all "nt_*" functions to one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 38942
diff changeset
2317
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2318 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
2319 {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2320 PyObject *val;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2321 char *node;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2322 int length;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2323
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2324 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
2325 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
2326 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
2327 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2328
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2329 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
2330 if (length == -3)
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2331 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2332 if (length == -2) {
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2333 raise_revlog_error();
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2334 return NULL;
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2335 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2336 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
2337 }
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2338
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2339 static void nt_dealloc(nodetree *self)
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2340 {
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2341 free(self->nodes);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2342 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
2343 }
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2344
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2345 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
2346 {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2347 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
2348 nt_dealloc(&self->nt);
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2349 PyObject_Del(self);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2350 }
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2351
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2352 static PyMethodDef ntobj_methods[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2353 {"insert", (PyCFunction)ntobj_insert, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2354 "insert an index entry"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2355 {"shortest", (PyCFunction)ntobj_shortest, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2356 "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
2357 {NULL} /* Sentinel */
39226
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2358 };
7a759ad2d06d shortest: use nodetree for finding shortest node within revset
Martin von Zweigbergk <martinvonz@google.com>
parents: 39225
diff changeset
2359
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2360 static PyTypeObject nodetreeType = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2361 PyVarObject_HEAD_INIT(NULL, 0) /* header */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2362 "parsers.nodetree", /* tp_name */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2363 sizeof(nodetreeObject), /* tp_basicsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2364 0, /* tp_itemsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2365 (destructor)ntobj_dealloc, /* tp_dealloc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2366 0, /* tp_print */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2367 0, /* tp_getattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2368 0, /* tp_setattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2369 0, /* tp_compare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2370 0, /* tp_repr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2371 0, /* tp_as_number */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2372 0, /* tp_as_sequence */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2373 0, /* tp_as_mapping */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2374 0, /* tp_hash */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2375 0, /* tp_call */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2376 0, /* tp_str */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2377 0, /* tp_getattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2378 0, /* tp_setattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2379 0, /* tp_as_buffer */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2380 Py_TPFLAGS_DEFAULT, /* tp_flags */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2381 "nodetree", /* tp_doc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2382 0, /* tp_traverse */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2383 0, /* tp_clear */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2384 0, /* tp_richcompare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2385 0, /* tp_weaklistoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2386 0, /* tp_iter */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2387 0, /* tp_iternext */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2388 ntobj_methods, /* tp_methods */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2389 0, /* tp_members */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2390 0, /* tp_getset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2391 0, /* tp_base */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2392 0, /* tp_dict */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2393 0, /* tp_descr_get */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2394 0, /* tp_descr_set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2395 0, /* tp_dictoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2396 (initproc)ntobj_init, /* tp_init */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2397 0, /* tp_alloc */
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2398 };
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
2399
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2400 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
2401 {
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2402 if (!self->ntinitialized) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
2403 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
2404 nt_dealloc(&self->nt);
38912
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
2405 return -1;
d1bc0e7c862b index: extract a type for the nodetree
Martin von Zweigbergk <martinvonz@google.com>
parents: 38911
diff changeset
2406 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2407 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
2408 nt_dealloc(&self->nt);
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2409 return -1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2410 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2411 self->ntinitialized = 1;
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
2412 self->ntrev = (int)index_length(self);
16615
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2413 self->ntlookups = 1;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2414 self->ntmisses = 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2415 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2416 return 0;
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2417 }
96fa9dd1db38 parsers: factor out radix tree initialization
Bryan O'Sullivan <bryano@fb.com>
parents: 16614
diff changeset
2418
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2419 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2420 * Return values:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2421 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2422 * -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
2423 * -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
2424 * rest: valid rev
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2425 */
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2426 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
2427 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2428 int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2429
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2430 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
2431 return -3;
44bbc89ec5e0 revlog: remove micro-optimization for looking up only nullid
Martin von Zweigbergk <martinvonz@google.com>
parents: 38819
diff changeset
2432
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2433 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
2434 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
2435 if (rev >= -1)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2436 return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2437
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2438 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2439 * 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
2440 * 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
2441 * 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
2442 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2443 * 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
2444 * 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
2445 * 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
2446 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2447 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
2448 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
2449 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
2450 if (n == NULL)
37861
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
2451 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
2452 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
2453 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
2454 return -3;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2455 break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2456 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2457 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2458 } else {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2459 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
2460 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
2461 if (n == NULL)
a9d9802d577e revlog: don't say "not found" on internal error
Martin von Zweigbergk <martinvonz@google.com>
parents: 37860
diff changeset
2462 return -3;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2463 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
2464 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
2465 return -3;
16614
1d800eb9ba52 parsers: update ntrev when we stop scanning
Bryan O'Sullivan <bryano@fb.com>
parents: 16597
diff changeset
2466 }
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2467 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
2468 break;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2469 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2470 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2471 self->ntrev = rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2472 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2473
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2474 if (rev >= 0)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2475 return rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2476 return -2;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2477 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2478
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2479 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
2480 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2481 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2482 int rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2483
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2484 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
2485 long idx;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2486 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
2487 return NULL;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2488 }
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2489 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
2490 }
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2491
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2492 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
2493 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
2494 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
2495 if (rev >= -1)
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2496 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
2497 if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2498 raise_revlog_error();
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2499 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2500 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2501
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2502 /*
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2503 * 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
2504 */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2505 static int index_populate_nt(indexObject *self)
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2506 {
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2507 int rev;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2508 if (self->ntrev > 0) {
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2509 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
2510 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
2511 if (n == NULL)
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2512 return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2513 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
2514 return -1;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2515 }
37930
892592475094 revlog: use literal -1 instead of variable that always has that value
Martin von Zweigbergk <martinvonz@google.com>
parents: 37929
diff changeset
2516 self->ntrev = -1;
37929
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2517 }
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2518 return 0;
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2519 }
9c6d1d41b3e6 revlog: extract function for fully populating the radix tree
Martin von Zweigbergk <martinvonz@google.com>
parents: 37861
diff changeset
2520
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2521 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
2522 {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2523 const char *fullnode;
42067
b01bbb8ff1f2 cext: make revlog.c PY_SSIZE_T_CLEAN
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41283
diff changeset
2524 Py_ssize_t nodelen;
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2525 char *node;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2526 int rev, i;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2527
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
2528 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
2529 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2530
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
2531 if (nodelen < 1) {
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2532 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
2533 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2534 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2535
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2536 if (nodelen > 2 * self->nodelen) {
17353
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
2537 PyErr_SetString(PyExc_ValueError, "key too long");
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
2538 return NULL;
bde1185f406c revlog: don't try to partialmatch strings those length > 40
sorcerer
parents: 17165
diff changeset
2539 }
16665
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2540
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2541 for (i = 0; i < nodelen; i++)
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2542 hexdigit(node, i);
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2543 if (PyErr_Occurred()) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2544 /* input contains non-hex characters */
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2545 PyErr_Clear();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2546 Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2547 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2548
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2549 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
2550 return NULL;
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
2551 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
2552 return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2553 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
2554
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2555 switch (rev) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2556 case -4:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2557 raise_revlog_error();
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2558 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2559 case -2:
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2560 Py_RETURN_NONE;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2561 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
2562 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
2563 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2564
37860
a91f31a1e281 revlog: extract function for getting node from known-to-exist rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 37858
diff changeset
2565 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
2566 if (fullnode == NULL) {
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2567 return NULL;
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2568 }
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2569 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
2570 }
e410be860393 revlog: speed up prefix matching against nodes
Bryan O'Sullivan <bryano@fb.com>
parents: 16664
diff changeset
2571
37968
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2572 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
2573 {
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2574 PyObject *val;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2575 char *node;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2576 int length;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2577
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2578 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
2579 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
2580 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
2581 return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2582
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2583 self->ntlookups++;
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
2584 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
2585 return NULL;
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
2586 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
2587 return NULL;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
2588 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
2589 if (length == -3)
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2590 return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2591 if (length == -2) {
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2592 raise_revlog_error();
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2593 return NULL;
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2594 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2595 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
2596 }
0304f22497fa revlog: use node tree (native code) for shortest() calculation
Martin von Zweigbergk <martinvonz@google.com>
parents: 37930
diff changeset
2597
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2598 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
2599 {
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
2600 PyObject *val;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2601 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
2602 int rev;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2603
16679
2950d186a927 parsers: strictly check for 20-byte hashes where they're required
Bryan O'Sullivan <bryano@fb.com>
parents: 16641
diff changeset
2604 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
2605 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
2606 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
2607 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
2608 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
2609 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
2610 return NULL;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2611 if (rev == -2)
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2612 Py_RETURN_NONE;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2613 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
2614 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2615
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2616 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
2617 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2618 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2619
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2620 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
2621 long rev;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2622 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
2623 return -1;
fa33196088c4 revlog: replace PyInt_AS_LONG with a more portable helper function
Augie Fackler <augie@google.com>
parents: 40562
diff changeset
2624 }
38866
aa33988ad8ab index: return False for "len(index) in index"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38852
diff changeset
2625 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
2626 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2627
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2628 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
2629 return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2630
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2631 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
2632 case -3:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2633 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2634 case -2:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2635 return 0;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2636 default:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2637 return 1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2638 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2639 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
2640
43534
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2641 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
2642 {
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2643 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
2644 if (ret < 0)
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2645 return NULL;
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2646 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
2647 }
0c659fc20207 index: add a `has_node` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43532
diff changeset
2648
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2649 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
2650 {
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2651 char *node;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2652 int rev;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2653
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
2654 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
2655 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
2656 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
2657 if (rev >= -1)
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2658 return PyLong_FromLong(rev);
43552
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2659 if (rev == -2)
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2660 raise_revlog_error();
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2661 return NULL;
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2662 }
bd87114ce341 index: add a `rev` method (API)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43534
diff changeset
2663
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2664 typedef uint64_t bitmask;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2665
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2666 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2667 * 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
2668 * 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
2669 * "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
2670 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2671 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
2672 int revcount)
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2673 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2674 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
2675 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
2676 PyObject *gca = PyList_New(0);
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2677 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
2678 int maxrev = -1;
22399
9f490afcb067 parsers: use bitmask type consistently in find_gca_candidates
Henrik Stuart <hg@hstuart.dk>
parents: 21871
diff changeset
2679 bitmask sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2680 bitmask *seen;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2681
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2682 if (gca == NULL)
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2683 return PyErr_NoMemory();
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2684
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2685 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
2686 if (revs[i] > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2687 maxrev = revs[i];
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
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2690 seen = calloc(sizeof(*seen), maxrev + 1);
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2691 if (seen == NULL) {
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2692 Py_DECREF(gca);
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2693 return PyErr_NoMemory();
19727
3d07b4a2f743 parsers: correctly handle a failed allocation
Bryan O'Sullivan <bryano@fb.com>
parents: 19726
diff changeset
2694 }
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2695
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2696 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
2697 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
2698
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2699 interesting = revcount;
18988
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 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
2702 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
2703 int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2704
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2705 if (!sv)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2706 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2707
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2708 if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2709 interesting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2710 if (sv == allseen) {
51388
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
2711 if (pylist_append_owned(
cb5175edd225 cext: fix potential memory leaks of list items appended with PyList_Append
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49679
diff changeset
2712 gca, PyLong_FromLong(v)) == -1) {
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2713 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2714 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2715 sv |= poison;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2716 for (i = 0; i < revcount; i++) {
20555
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2717 if (revs[i] == v)
4add43865a9b ancestors: remove unnecessary handling of 'left'
Mads Kiilerich <madski@unity3d.com>
parents: 20554
diff changeset
2718 goto done;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2719 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2720 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2721 }
25810
82d6a35cf432 parsers: fix buffer overflow by invalid parent revision read from revlog
Yuya Nishihara <yuya@tcha.org>
parents: 25584
diff changeset
2722 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
2723 goto bail;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2724
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2725 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
2726 int p = parents[i];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2727 if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2728 continue;
19030
48d6f436363e parsers: fix variable declaration position issue
Matt Mackall <mpm@selenic.com>
parents: 18988
diff changeset
2729 sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2730 if (sv < poison) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2731 if (sp == 0) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2732 seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2733 interesting++;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2734 } 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
2735 seen[p] |= sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2736 } else {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2737 if (sp && sp < poison)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2738 interesting--;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2739 seen[p] = sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2740 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2741 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2742 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2743
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2744 done:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2745 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2746 return gca;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2747 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2748 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2749 Py_XDECREF(gca);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2750 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2751 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2752
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2753 /*
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2754 * 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
2755 * path to the root.
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2756 */
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2757 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
2758 {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2759 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
2760 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
2761 int *depth, *interesting = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2762 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
2763 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
2764 long *seen = NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2765 int maxrev = -1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2766 long final;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2767
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2768 if (revcount > capacity) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2769 PyErr_Format(PyExc_OverflowError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2770 "bitset size (%ld) > capacity (%ld)",
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2771 (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
2772 return NULL;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2773 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2774
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2775 for (i = 0; i < revcount; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2776 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
2777 if (n > maxrev)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2778 maxrev = n;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2779 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2780
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2781 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
2782 if (depth == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2783 return PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2784
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2785 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
2786 if (seen == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2787 PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2788 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2789 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2790
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
2791 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
2792 if (interesting == NULL) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2793 PyErr_NoMemory();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2794 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2795 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2796
19502
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
2797 if (PyList_Sort(revs) == -1)
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
2798 goto bail;
8704477ad3b6 ancestor.deepest: sort revs in C version
Siddharth Agarwal <sid0@fb.com>
parents: 19062
diff changeset
2799
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2800 for (i = 0; i < revcount; i++) {
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2801 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
2802 long b = 1l << i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2803 depth[n] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2804 seen[n] = b;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2805 interesting[b] = 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2806 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2807
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2808 /* 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
2809 * interesting. */
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2810 ninteresting = (int)revcount;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2811
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2812 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
2813 int dv = depth[v];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2814 int parents[2];
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2815 long sv;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2816
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2817 if (dv == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2818 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2819
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2820 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
2821 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
2822 goto bail;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2823
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2824 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
2825 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
2826 long sp;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2827 int dp;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2828
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2829 if (p == -1)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2830 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2831
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2832 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
2833 sp = seen[p];
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2834 if (dp <= dv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2835 depth[p] = dv + 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2836 if (sp != sv) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2837 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
2838 seen[p] = sv;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2839 if (sp) {
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2840 interesting[sp] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2841 if (interesting[sp] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2842 ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2843 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2844 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2845 } 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
2846 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
2847 if (nsp == sp)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2848 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2849 seen[p] = nsp;
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
2850 interesting[sp] -= 1;
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2851 if (interesting[sp] == 0)
19503
f2dfda6ac152 ancestor.deepest: decrement ninteresting correctly (issue3984)
Wei, Elson <elson.wei@gmail.com>
parents: 19502
diff changeset
2852 ninteresting -= 1;
33475
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2853 if (interesting[nsp] == 0)
f501322512b6 parsers: fix invariant bug in find_deepest (issue5623)
Sune Foldager <cryo@cyanite.org>
parents: 33174
diff changeset
2854 ninteresting += 1;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2855 interesting[nsp] += 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2856 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2857 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2858 interesting[sv] -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2859 if (interesting[sv] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2860 ninteresting -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2861 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2862
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2863 final = 0;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2864 j = ninteresting;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2865 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
2866 if (interesting[i] == 0)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2867 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2868 final |= i;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2869 j -= 1;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2870 }
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2871 if (final == 0) {
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2872 keys = PyList_New(0);
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2873 goto bail;
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2874 }
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2875
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2876 dict = PyDict_New();
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2877 if (dict == NULL)
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2878 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2879
19504
2fa303619b4d ancestor.deepest: ignore ninteresting while building result (issue3984)
Siddharth Agarwal <sid0@fb.com>
parents: 19503
diff changeset
2880 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
2881 PyObject *key;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2882
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2883 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
2884 continue;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2885
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2886 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
2887 Py_INCREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2888 Py_INCREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2889 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
2890 Py_DECREF(key);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2891 Py_DECREF(Py_None);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2892 goto bail;
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2893 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2894 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2895
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2896 keys = PyDict_Keys(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2897
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2898 bail:
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2899 free(depth);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2900 free(seen);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2901 free(interesting);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2902 Py_XDECREF(dict);
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2903
21730
8da100383dc3 parsers.c: fix a couple of memory leaks
Danek Duvall <danek.duvall@oracle.com>
parents: 21103
diff changeset
2904 return keys;
18988
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2905 }
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2906
5bae936764bb parsers: a C implementation of the new ancestors algorithm
Bryan O'Sullivan <bryano@fb.com>
parents: 18900
diff changeset
2907 /*
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2908 * Given a (possibly overlapping) set of revs, return all the
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2909 * common ancestors heads: heads(::args[0] and ::a[1] and ...)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2910 */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2911 static PyObject *index_commonancestorsheads(indexObject *self, PyObject *args)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2912 {
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
2913 PyObject *ret = NULL;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2914 Py_ssize_t argcount, i, len;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2915 bitmask repeat = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2916 int revcount = 0;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2917 int *revs;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2918
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2919 argcount = PySequence_Length(args);
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
2920 revs = PyMem_Malloc(argcount * sizeof(*revs));
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2921 if (argcount > 0 && revs == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2922 return PyErr_NoMemory();
38851
781b2720d2ac index: don't include nullid in len()
Martin von Zweigbergk <martinvonz@google.com>
parents: 38850
diff changeset
2923 len = index_length(self);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2924
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2925 for (i = 0; i < argcount; i++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2926 static const int capacity = 24;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2927 PyObject *obj = PySequence_GetItem(args, i);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2928 bitmask x;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2929 long val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2930
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2931 if (!PyLong_Check(obj)) {
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2932 PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2933 "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
2934 Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2935 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2936 }
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2937 val = PyLong_AsLong(obj);
23945
33d6aaf84c9e parsers.c: fix a memory leak in index_commonancestorsheads
Augie Fackler <augie@google.com>
parents: 23944
diff changeset
2938 Py_DECREF(obj);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2939 if (val == -1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2940 ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2941 goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2942 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2943 if (val < 0 || val >= len) {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2944 PyErr_SetString(PyExc_IndexError, "index out of range");
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2945 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2946 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2947 /* this cheesy bloom filter lets us avoid some more
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2948 * expensive duplicate checks in the common set-is-disjoint
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2949 * case */
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2950 x = 1ull << (val & 0x3f);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2951 if (repeat & x) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2952 int k;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2953 for (k = 0; k < revcount; k++) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2954 if (val == revs[k])
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2955 goto duplicate;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2956 }
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2957 } else
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2958 repeat |= x;
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2959 if (revcount >= capacity) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2960 PyErr_Format(PyExc_OverflowError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2961 "bitset size (%d) > capacity (%d)",
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
2962 revcount, capacity);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2963 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2964 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2965 revs[revcount++] = (int)val;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2966 duplicate:;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2967 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2968
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2969 if (revcount == 0) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2970 ret = PyList_New(0);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2971 goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2972 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2973 if (revcount == 1) {
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2974 PyObject *obj;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2975 ret = PyList_New(1);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2976 if (ret == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2977 goto bail;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
2978 obj = PyLong_FromLong(revs[0]);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2979 if (obj == NULL)
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2980 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2981 PyList_SET_ITEM(ret, 0, obj);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2982 goto done;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2983 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2984
21103
628c16489d1c parsers: remove unnecessary gca variable in index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 21102
diff changeset
2985 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
2986 if (ret == NULL)
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2987 goto bail;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2988
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2989 done:
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
2990 PyMem_Free(revs);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2991 return ret;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2992
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2993 bail:
31469
a43fd9ec2a39 parsers: use Python memory allocator in commonancestorsheads()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31426
diff changeset
2994 PyMem_Free(revs);
21102
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2995 Py_XDECREF(ret);
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2996 return NULL;
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2997 }
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2998
4eb6553789e1 parsers: introduce index_commonancestorsheads
Mads Kiilerich <madski@unity3d.com>
parents: 20797
diff changeset
2999 /*
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3000 * 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
3001 * 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
3002 */
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3003 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
3004 {
26048
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
3005 PyObject *ret;
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3006 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
3007 if (gca == NULL)
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3008 return NULL;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3009
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3010 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
3011 return gca;
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3012 }
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3013
26048
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
3014 ret = find_deepest(self, gca);
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
3015 Py_DECREF(gca);
0be2f81aadc3 parsers: fix two leaks in index_ancestors
Augie Fackler <augie@google.com>
parents: 26044
diff changeset
3016 return ret;
24004
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3017 }
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3018
8a5267cd5286 parsers: rewrite index_ancestors() in terms of index_commonancestorsheads()
Martin von Zweigbergk <martinvonz@google.com>
parents: 23948
diff changeset
3019 /*
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3020 * 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
3021 */
38942
3e74c01102af index: rename "nt_*(indexObject *self,...)" functions to "index_*"
Martin von Zweigbergk <martinvonz@google.com>
parents: 38941
diff changeset
3022 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
3023 {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3024 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
3025
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3026 len = self->length + self->new_length;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3027 i = start - self->length;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3028 if (i < 0)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3029 return;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3030
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
3031 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
3032 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
3033 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
3034 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3035
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3036 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
3037 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3038
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3039 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3040 * 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
3041 * range.
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3042 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3043 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
3044 {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3045 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
3046 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
3047 int ret = 0;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3048
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3049 if (PySlice_GetIndicesEx(item, length, &start, &stop, &step,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3050 &slicelength) < 0)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3051 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3052
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3053 if (slicelength <= 0)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3054 return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3055
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3056 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
3057 stop = start;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3058
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3059 if (step < 0) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3060 stop = start + 1;
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3061 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
3062 step = -step;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3063 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3064
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3065 if (step != 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3066 PyErr_SetString(PyExc_ValueError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3067 "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
3068 return -1;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3069 }
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3070
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3071 if (stop != length - 1) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3072 PyErr_SetString(PyExc_IndexError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3073 "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
3074 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3075 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3076
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
3077 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
3078 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
3079 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
3080
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
3081 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
3082 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
3083 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
3084 return -1;
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3085
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3086 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
3087 }
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3088 if (self->new_length)
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3089 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
3090 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
3091 self->ntrev = (int)start;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3092 } else if (self->new_length) {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3093 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
3094 }
43847
49fa0b31ee1d cext-revlog: fixed __delitem__ for uninitialized nodetree
Georges Racinet <georges.racinet@octobus.net>
parents: 43582
diff changeset
3095
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
3096 self->length = start;
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
3097 goto done;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3098 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3099
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3100 if (self->ntinitialized) {
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3101 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
3102 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
3103 self->ntrev = (int)start;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3104 } else {
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3105 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
3106 }
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
3107 done:
16787
bda96ce993f9 parsers: cache the result of index_headrevs
Bryan O'Sullivan <bryano@fb.com>
parents: 16786
diff changeset
3108 Py_CLEAR(self->headrevs);
16784
12a852c7c763 parsers: reduce raw_length when truncating
Bryan O'Sullivan <bryano@fb.com>
parents: 16732
diff changeset
3109 return ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3110 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3111
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3112 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3113 * Supported ops:
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3114 *
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3115 * slice deletion
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3116 * 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
3117 * 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
3118 */
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3119 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
3120 PyObject *value)
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3121 {
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3122 char *node;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3123 long rev;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3124
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3125 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
3126 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
3127
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3128 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
3129 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3130
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3131 if (value == NULL)
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3132 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
3133 : 0;
48818
13d705c98914 cext: use PyLong symbols
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48769
diff changeset
3134 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
3135 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
3136 if (!PyErr_Occurred())
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3137 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
3138 return -1;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3139 }
23468
ee311681e591 parsers: ensure revlog index node tree is initialized before insertion
Mike Edgar <adgar@google.com>
parents: 23087
diff changeset
3140
38941
c0b6a7c78a21 index: split up nt_init() in two
Martin von Zweigbergk <martinvonz@google.com>
parents: 38940
diff changeset
3141 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
3142 return -1;
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3143 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
3144 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3145
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3146 /*
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3147 * 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
3148 * 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
3149 */
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
3150 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
3151 {
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3152 const char *data = (const char *)self->buf.buf;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
3153 Py_ssize_t pos = 0;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3154 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
3155 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
3156 Py_ssize_t len = 0;
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
3157
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3158 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
3159 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
3160 /* 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
3161 if (self->format_version == format_v1) {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3162 comp_len =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3163 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
3164 sidedata_comp_len = 0;
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3165 } 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
3166 comp_len =
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3167 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
3168 sidedata_comp_len = getbe32(
48722
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3169 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
3170 } else {
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3171 raise_revlog_error();
92b5a2c4d637 revlog: split revlog v1 and revlog v2 handling
pacien <pacien.trangirard@pacien.net>
parents: 48721
diff changeset
3172 return -1;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3173 }
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3174 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
3175 if (offsets)
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
3176 offsets[len] = data + pos;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3177 len++;
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
3178 pos += incr;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3179 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
3180
20167
09e41ac6289d mpatch: rewrite pointer overflow checks
Matt Mackall <mpm@selenic.com>
parents: 20109
diff changeset
3181 if (pos != end) {
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3182 if (!PyErr_Occurred())
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3183 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
3184 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3185 }
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 return len;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3188 }
13254
5ef5eb1f3515 revlog: only build the nodemap on demand
Matt Mackall <mpm@selenic.com>
parents: 11361
diff changeset
3189
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3190 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
3191 {
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3192 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
3193 Py_ssize_t size;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3194
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3195 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
3196
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3197 /* 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
3198 */
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3199 self->added = NULL;
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3200 self->new_length = 0;
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3201 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
3202 self->data = NULL;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3203 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
3204 self->headrevs = NULL;
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
3205 self->filteredrevs = Py_None;
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
3206 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
3207 self->ntinitialized = 0;
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3208 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
3209 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
3210 self->nullentry = NULL;
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 49679
diff changeset
3211 self->rust_ext_compat = 0;
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3212 self->format_version = format_v1;
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3213
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3214 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
3215 &data_obj, &inlined_obj,
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3216 &(self->format_version)))
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3217 return -1;
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3218 if (!PyObject_CheckBuffer(data_obj)) {
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3219 PyErr_SetString(PyExc_TypeError,
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3220 "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
3221 return -1;
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3222 }
46144
e4f6dae01b3b cext: shut-up sign compare warnings
Joerg Sonnenberger <joerg@bec.de>
parents: 46141
diff changeset
3223 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
3224 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
3225 return -1;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3226 }
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3227
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3228 if (self->format_version == format_v1) {
51239
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 49679
diff changeset
3229 self->rust_ext_compat = 1;
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3230 self->entry_size = v1_entry_size;
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3231 } 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
3232 self->entry_size = v2_entry_size;
48769
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3233 } else if (self->format_version == format_cl2) {
1bb62821f080 revlog: register changelogv2 C implementation in parsers
pacien <pacien.trangirard@pacien.net>
parents: 48768
diff changeset
3234 self->entry_size = cl2_entry_size;
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3235 }
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3236
48821
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
3237 self->nullentry = Py_BuildValue(
b0dd39b91e7a cext: remove PY23()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48820
diff changeset
3238 "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
3239 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
3240
46141
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3241 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
3242 return -1;
41733a1c3532 cext: isolate hash size in the revlog handling in a single place
Joerg Sonnenberger <joerg@bec.de>
parents: 46078
diff changeset
3243 PyObject_GC_UnTrack(self->nullentry);
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3244
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3245 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
3246 return -1;
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3247 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
3248
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3249 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
3250 self->data = data_obj;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3251
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3252 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
3253 self->ntrev = -1;
16597
b767382a8675 parsers: fix refcount bug on corrupt index
Matt Mackall <mpm@selenic.com>
parents: 16572
diff changeset
3254 Py_INCREF(self->data);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3255
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3256 if (self->inlined) {
22401
9ba8a93e55f5 parsers: ensure correct return type for inline_scan
Henrik Stuart <hg@hstuart.dk>
parents: 22400
diff changeset
3257 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
3258 if (len == -1)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3259 goto bail;
39068
52e9bf215f96 index: don't include nullid in the internal "length" field
Martin von Zweigbergk <martinvonz@google.com>
parents: 38944
diff changeset
3260 self->length = len;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3261 } 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
3262 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
3263 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
3264 goto bail;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3265 }
47140
c55afa35a5c8 revlog: rename `hdrsize` to `entry_size` in the C code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47078
diff changeset
3266 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
3267 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3268
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3269 return 0;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3270 bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3271 return -1;
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3272 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3273
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3274 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
3275 {
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3276 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
3277 return (PyObject *)self;
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3278 }
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3279
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3280 static void _index_clearcaches(indexObject *self)
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3281 {
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3282 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
3283 PyMem_Free((void *)self->offsets);
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3284 self->offsets = NULL;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3285 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3286 if (self->ntinitialized) {
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3287 nt_dealloc(&self->nt);
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3288 }
39291
9f097214fbf3 index: embed nodetree in index object to avoid reference cycle
Martin von Zweigbergk <martinvonz@google.com>
parents: 39228
diff changeset
3289 self->ntinitialized = 0;
38944
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3290 Py_CLEAR(self->headrevs);
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3291 }
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3292
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3293 static PyObject *index_clearcaches(indexObject *self)
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3294 {
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3295 _index_clearcaches(self);
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3296 self->ntrev = -1;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3297 self->ntlookups = self->ntmisses = 0;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3298 Py_RETURN_NONE;
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3299 }
c1de67691d5b index: move index_clearcaches() further down
Martin von Zweigbergk <martinvonz@google.com>
parents: 38943
diff changeset
3300
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3301 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
3302 {
16370
28bb4daf070c parsers: fix a memleak, and add a clearcaches method to the index
Bryan O'Sullivan <bryano@fb.com>
parents: 16363
diff changeset
3303 _index_clearcaches(self);
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 22403
diff changeset
3304 Py_XDECREF(self->filteredrevs);
30577
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3305 if (self->buf.buf) {
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3306 PyBuffer_Release(&self->buf);
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3307 memset(&self->buf, 0, sizeof(self->buf));
6146d5acee69 parsers: use buffer to store revlog index
Jun Wu <quark@fb.com>
parents: 30171
diff changeset
3308 }
20109
e57c532c3835 parse_index2: fix crash on bad argument type (issue4110)
Chris Jerdonek <chris.jerdonek@gmail.com>
parents: 19728
diff changeset
3309 Py_XDECREF(self->data);
45936
0ce15a8c7b8b revlog: store new index entries as binary
Joerg Sonnenberger <joerg@bec.de>
parents: 45811
diff changeset
3310 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
3311 Py_XDECREF(self->nullentry);
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3312 PyObject_Del(self);
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3313 }
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3314
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3315 static PySequenceMethods index_sequence_methods = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3316 (lenfunc)index_length, /* sq_length */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3317 0, /* sq_concat */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3318 0, /* sq_repeat */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3319 (ssizeargfunc)index_get, /* sq_item */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3320 0, /* sq_slice */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3321 0, /* sq_ass_item */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3322 0, /* sq_ass_slice */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3323 (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
3324 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3325
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3326 static PyMappingMethods index_mapping_methods = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3327 (lenfunc)index_length, /* mp_length */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3328 (binaryfunc)index_getitem, /* mp_subscript */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3329 (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
3330 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3331
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3332 static PyMethodDef index_methods[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3333 {"ancestors", (PyCFunction)index_ancestors, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3334 "return the gca set of the given revs"},
51396
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
3335 {"headrevsdiff", (PyCFunction)index_headrevsdiff, METH_VARARGS,
3f37d80d3ab4 revlog: add a C implementation of `headrevsdiff`
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51394
diff changeset
3336 "return the set of heads removed/added by a range of commits"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3337 {"commonancestorsheads", (PyCFunction)index_commonancestorsheads,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3338 METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3339 "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
3340 {"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3341 "clear the index caches"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3342 {"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
3343 {"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
3344 "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
3345 {"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
3346 "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
3347 {"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
3348 "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
3349 {"computephasesmapsets", (PyCFunction)compute_phases_map_sets, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3350 "compute phases"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3351 {"reachableroots2", (PyCFunction)reachableroots2, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3352 "reachableroots"},
46717
502e795b55ac revlog-index: add `replace_sidedata_info` method
Raphaël Gomès <rgomes@octobus.net>
parents: 46708
diff changeset
3353 {"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
3354 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
3355 {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3356 "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
3357 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3358 "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
3359 {"issnapshot", (PyCFunction)index_issnapshot, METH_O,
a28833d79aca revlog: use the native implementation of issnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41085
diff changeset
3360 "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
3361 {"findsnapshots", (PyCFunction)index_findsnapshots, METH_VARARGS,
38e88450138c delta: have a native implementation of _findsnapshot
Boris Feld <boris.feld@octobus.net>
parents: 41086
diff changeset
3362 "Gather snapshot data in a cache dict"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3363 {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3364 "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
3365 {"slicechunktodensity", (PyCFunction)index_slicechunktodensity,
cc76ca9fca20 sparse-revlog: introduce native (C) implementation of slicechunktodensity
Boris Feld <boris.feld@octobus.net>
parents: 40706
diff changeset
3366 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
3367 {"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
3368 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3369 "match a potentially ambiguous node ID"},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3370 {"shortest", (PyCFunction)index_shortest, METH_VARARGS,
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3371 "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
3372 {"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
3373 {"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
3374 "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
3375 {"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
3376 "pack the revlog header information into binary"},
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3377 {NULL} /* Sentinel */
16414
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3378 };
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3379
e8d37b78acfb parsers: use base-16 trie for faster node->rev mapping
Bryan O'Sullivan <bryano@fb.com>
parents: 16393
diff changeset
3380 static PyGetSetDef index_getset[] = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3381 {"nodemap", (getter)index_nodemap, NULL, "nodemap", NULL},
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3382 {NULL} /* Sentinel */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3383 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3384
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
3385 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
3386 {"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
3387 "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
3388 {"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
3389 "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
3390 {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
3391 };
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
3392
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3393 PyTypeObject HgRevlogIndex_Type = {
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3394 PyVarObject_HEAD_INIT(NULL, 0) /* header */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3395 "parsers.index", /* tp_name */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3396 sizeof(indexObject), /* tp_basicsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3397 0, /* tp_itemsize */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3398 (destructor)index_dealloc, /* tp_dealloc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3399 0, /* tp_print */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3400 0, /* tp_getattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3401 0, /* tp_setattr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3402 0, /* tp_compare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3403 0, /* tp_repr */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3404 0, /* tp_as_number */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3405 &index_sequence_methods, /* tp_as_sequence */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3406 &index_mapping_methods, /* tp_as_mapping */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3407 0, /* tp_hash */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3408 0, /* tp_call */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3409 0, /* tp_str */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3410 0, /* tp_getattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3411 0, /* tp_setattro */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3412 0, /* tp_as_buffer */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3413 Py_TPFLAGS_DEFAULT, /* tp_flags */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3414 "revlog index", /* tp_doc */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3415 0, /* tp_traverse */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3416 0, /* tp_clear */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3417 0, /* tp_richcompare */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3418 0, /* tp_weaklistoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3419 0, /* tp_iter */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3420 0, /* tp_iternext */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3421 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
3422 index_members, /* tp_members */
40562
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3423 index_getset, /* tp_getset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3424 0, /* tp_base */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3425 0, /* tp_dict */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3426 0, /* tp_descr_get */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3427 0, /* tp_descr_set */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3428 0, /* tp_dictoffset */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3429 (initproc)index_init, /* tp_init */
e5ad3ef90aa1 revlog: give formatting to clang-format
Augie Fackler <augie@google.com>
parents: 40561
diff changeset
3430 0, /* tp_alloc */
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3431 };
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3432
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3433 /*
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3434 * 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
3435 * follows:
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3436 *
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3437 * 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
3438 * 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
3439 * 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
3440 *
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3441 * added complications are for backwards compatibility
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3442 */
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3443 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
3444 {
45173
2bc5d1531235 revlog: fix excessive decref on tuple creation failure in parse_index2()
Yuya Nishihara <yuya@tcha.org>
parents: 45141
diff changeset
3445 PyObject *cache = NULL;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3446 indexObject *idx;
16572
8d44b5a2974f parsers: fix refcount leak, simplify init of index (issue3417)
Bryan O'Sullivan <bryano@fb.com>
parents: 16437
diff changeset
3447 int ret;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3448
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3449 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
3450 if (idx == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3451 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3452
46708
358737abeeef cext: add support for revlogv2
Raphaël Gomès <rgomes@octobus.net>
parents: 46328
diff changeset
3453 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
3454 if (ret == -1)
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3455 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3456
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3457 if (idx->inlined) {
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3458 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
3459 if (cache == NULL)
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3460 goto bail;
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3461 } else {
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3462 cache = Py_None;
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3463 Py_INCREF(cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3464 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3465
45173
2bc5d1531235 revlog: fix excessive decref on tuple creation failure in parse_index2()
Yuya Nishihara <yuya@tcha.org>
parents: 45141
diff changeset
3466 return Py_BuildValue("NN", idx, cache);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3467
16363
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3468 bail:
2cdd7e63211b parsers: incrementally parse the revlog index in C
Bryan O'Sullivan <bryano@fb.com>
parents: 15033
diff changeset
3469 Py_XDECREF(idx);
7108
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3470 Py_XDECREF(cache);
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3471 return NULL;
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3472 }
1ca878d7b849 C implementation of revlog index parsing
Bernhard Leiner <bleiner@gmail.com>
parents: 7093
diff changeset
3473
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3474 static Revlog_CAPI CAPI = {
44066
f5d2720f3bea revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents: 43959
diff changeset
3475 /* 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
3476 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
3477 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
3478 };
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3479
32378
7d0c69505a66 cext: extract revlog/index parsing code to own C file
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32372
diff changeset
3480 void revlog_module_init(PyObject *mod)
24017
72c9b5ae7278 parsers: add fm1readmarker
Augie Fackler <augie@google.com>
parents: 24004
diff changeset
3481 {
41052
4c25038c112c rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents: 40963
diff changeset
3482 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
3483 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
3484 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
3485 return;
40860
18a8def6e1b5 revlog: rename indexType to HgRevlogIndex_Type as it's a global symbol
Yuya Nishihara <yuya@tcha.org>
parents: 40859
diff changeset
3486 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
3487 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
3488
39218
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3489 nodetreeType.tp_new = PyType_GenericNew;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3490 if (PyType_Ready(&nodetreeType) < 0)
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3491 return;
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3492 Py_INCREF(&nodetreeType);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3493 PyModule_AddObject(mod, "nodetree", (PyObject *)&nodetreeType);
b85b377e7fc2 index: make node tree a Python object
Martin von Zweigbergk <martinvonz@google.com>
parents: 39075
diff changeset
3494
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3495 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
3496 if (caps != NULL)
43959
f384d68d8ea8 revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents: 43847
diff changeset
3497 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
3498 }